CI: Fix missing () in gates.jenkinsfile
[asterisk/asterisk.git] / tests / test_data_buffer.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2018, Digium, Inc.
5  *
6  * Ben Ford <bford@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Media Stream API Unit Tests
22  *
23  * \author Ben Ford <bford@digium.com>
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>TEST_FRAMEWORK</depend>
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 #include "asterisk/module.h"
35 #include "asterisk/test.h"
36 #include "asterisk/data_buffer.h"
37
38 #define BUFFER_MAX_NOMINAL 10
39
40 struct mock_payload
41 {
42         int id;
43 };
44
45 /* Ensures that RAII_VAR will not trip ast_assert(buffer != NULL) in the callback */
46 static void ast_data_buffer_free_wrapper(struct ast_data_buffer *buffer)
47 {
48         if (!buffer) {
49                 return;
50         }
51
52         ast_data_buffer_free(buffer);
53 }
54
55 AST_TEST_DEFINE(buffer_create)
56 {
57         RAII_VAR(struct ast_data_buffer *, buffer, NULL, ast_data_buffer_free_wrapper);
58
59         switch (cmd) {
60         case TEST_INIT:
61                 info->name = "buffer_create";
62                 info->category = "/main/data_buffer/";
63                 info->summary = "buffer create unit test";
64                 info->description =
65                         "Test that creating a data buffer results in a buffer with the expected values";
66                 return AST_TEST_NOT_RUN;
67         case TEST_EXECUTE:
68                 break;
69         }
70
71         buffer = ast_data_buffer_alloc(ast_free_ptr, BUFFER_MAX_NOMINAL);
72
73         ast_test_validate(test, buffer != NULL,
74                         "Failed to create buffer with valid arguments");
75         ast_test_validate(test, ast_data_buffer_count(buffer) == 0,
76                         "Newly created buffer does not have the expected payload count");
77         ast_test_validate(test, ast_data_buffer_max(buffer) == BUFFER_MAX_NOMINAL,
78                         "Newly created buffer does not have the expected max size");
79
80         return AST_TEST_PASS;
81 }
82
83 AST_TEST_DEFINE(buffer_put)
84 {
85         RAII_VAR(struct ast_data_buffer *, buffer, NULL, ast_data_buffer_free_wrapper);
86         struct mock_payload *payload;
87         struct mock_payload *fetched_payload;
88         int ret;
89
90         switch (cmd) {
91         case TEST_INIT:
92                 info->name = "buffer_put";
93                 info->category = "/main/data_buffer/";
94                 info->summary = "buffer put unit test";
95                 info->description =
96                         "Test that putting payloads in the buffer yields the expected results";
97                 return AST_TEST_NOT_RUN;
98         case TEST_EXECUTE:
99                 break;
100         }
101
102         buffer = ast_data_buffer_alloc(ast_free_ptr, 2);
103
104         ast_test_validate(test, buffer != NULL,
105                         "Failed to create buffer with valid arguments");
106         ast_test_validate(test, ast_data_buffer_count(buffer) == 0,
107                         "Newly created buffer is not empty");
108
109         payload = ast_calloc(1, sizeof(*payload));
110
111         ast_test_validate(test, payload != NULL,
112                         "Failed to allocate memory for first payload");
113
114         payload->id = 2;
115         ret = ast_data_buffer_put(buffer, 2, payload);
116
117         ast_test_validate(test, ret == 0,
118                         "Adding a payload to an empty buffer did not return the expected value");
119         ast_test_validate(test, ast_data_buffer_count(buffer) == 1,
120                         "Adding a payload to an empty buffer did not update count to the expected value");
121
122         fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, 2);
123
124         ast_test_validate(test, fetched_payload != NULL,
125                         "Failed to get only payload from buffer given valid arguments");
126
127         ast_data_buffer_put(buffer, 2, payload);
128
129         ast_test_validate(test, ast_data_buffer_count(buffer) == 1,
130                         "Adding a payload that is already in the buffer should not do anything");
131
132         payload = ast_calloc(1, sizeof(*payload));
133
134         ast_test_validate(test, payload != NULL,
135                         "Failed to allocate memory for second payload");
136
137         payload->id = 1;
138         ast_data_buffer_put(buffer, 1, payload);
139         fetched_payload = ast_data_buffer_get(buffer, 1);
140
141         ast_test_validate(test, fetched_payload != NULL,
142                         "Failed to get a payload from buffer given valid arguments");
143         ast_test_validate(test, ast_data_buffer_count(buffer) == 2,
144                         "Buffer does not have the expected count after removing a payload");
145         ast_test_validate(test, fetched_payload->id == 1,
146                         "Did not get the expected payload from the buffer");
147
148         payload = ast_calloc(1, sizeof(*payload));
149
150         ast_test_validate(test, payload != NULL,
151                         "Failed to allocate memory for third payload");
152
153         payload->id = 3;
154         ret = ast_data_buffer_put(buffer, 3, payload);
155
156         ast_test_validate(test, ret == 0,
157                         "Failed to replace a payload in the buffer");
158         ast_test_validate(test, ast_data_buffer_count(buffer) <= 2,
159                         "Buffer count exceeded the max");
160
161         fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, 3);
162
163         ast_test_validate(test, fetched_payload != NULL,
164                         "Failed to get a payload from buffer at position 3 given valid arguments");
165         ast_test_validate(test, fetched_payload->id == 3,
166                         "Did not get the expected payload at position 3 from the buffer");
167
168         fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, 2);
169
170         ast_test_validate(test, fetched_payload != NULL,
171                         "Failed to get a payload from buffer at position 2 given valid arguments");
172         ast_test_validate(test, fetched_payload->id == 2,
173                         "Did not get the expected payload at position 2 from the buffer");
174
175         return AST_TEST_PASS;
176 }
177
178 AST_TEST_DEFINE(buffer_resize)
179 {
180         RAII_VAR(struct ast_data_buffer *, buffer, NULL, ast_data_buffer_free_wrapper);
181
182         switch (cmd) {
183         case TEST_INIT:
184                 info->name = "buffer_resize";
185                 info->category = "/main/data_buffer/";
186                 info->summary = "buffer resize unit test";
187                 info->description =
188                         "Tests resizing a data buffer to make sure it has the expected outcome";
189                 return AST_TEST_NOT_RUN;
190         case TEST_EXECUTE:
191                 break;
192         }
193
194         buffer = ast_data_buffer_alloc(ast_free_ptr, BUFFER_MAX_NOMINAL);
195
196         ast_test_validate(test, buffer != NULL,
197                         "Failed to create buffer with valid arguments");
198
199         ast_data_buffer_resize(buffer, BUFFER_MAX_NOMINAL);
200
201         ast_test_validate(test, ast_data_buffer_max(buffer) == BUFFER_MAX_NOMINAL,
202                         "Trying to resize buffer to same size should not change its max size");
203
204         ast_data_buffer_resize(buffer, BUFFER_MAX_NOMINAL + 2);
205
206         ast_test_validate(test, ast_data_buffer_max(buffer) == BUFFER_MAX_NOMINAL + 2,
207                         "Increasing buffer size did not return the expected max");
208
209         ast_data_buffer_resize(buffer, 1);
210
211         ast_test_validate(test, ast_data_buffer_max(buffer) == 1,
212                         "Decreasing buffer size did not return the expected max");
213
214         return AST_TEST_PASS;
215 }
216
217 AST_TEST_DEFINE(buffer_nominal)
218 {
219         RAII_VAR(struct ast_data_buffer *, buffer, NULL, ast_data_buffer_free_wrapper);
220         RAII_VAR(struct mock_payload *, removed_payload, NULL, ast_free_ptr);
221         struct mock_payload *payload;
222         struct mock_payload *fetched_payload;
223         int ret;
224         int i;
225
226         switch (cmd) {
227         case TEST_INIT:
228                 info->name = "buffer_nominal";
229                 info->category = "/main/data_buffer/";
230                 info->summary = "buffer nominal unit test";
231                 info->description =
232                         "Tests the normal usage of a data buffer to ensure the expected payloads "
233                         "are present after multiple insertions";
234                 return AST_TEST_NOT_RUN;
235         case TEST_EXECUTE:
236                 break;
237         }
238
239         buffer = ast_data_buffer_alloc(ast_free_ptr, BUFFER_MAX_NOMINAL);
240
241         ast_test_validate(test, buffer != NULL,
242                         "Failed to create buffer with valid arguments");
243
244         for (i = 1; i <= BUFFER_MAX_NOMINAL; i++) {
245                 payload = ast_calloc(1, sizeof(*payload));
246
247                 ast_test_validate(test, payload != NULL,
248                                 "Failed to allocate memory for payload %d", i);
249
250                 ret = ast_data_buffer_put(buffer, i, payload);
251                 if (ret) {
252                         ast_free(payload);
253                 }
254
255                 ast_test_validate(test, ret == 0,
256                                 "Failed to add payload %d to buffer", i);
257         }
258
259         ast_test_validate(test, ast_data_buffer_count(buffer) == BUFFER_MAX_NOMINAL,
260                         "Buffer does not have the expected count after adding payloads");
261
262         for (i = 1; i <= BUFFER_MAX_NOMINAL; i++) {
263                 fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, i);
264
265                 ast_test_validate(test, fetched_payload != NULL,
266                                 "Failed to get payload at position %d during first loop", i);
267         }
268
269         for (i = 1; i <= BUFFER_MAX_NOMINAL; i++) {
270                 payload = ast_calloc(1, sizeof(*payload));
271
272                 ast_test_validate(test, payload != NULL,
273                                 "Failed to allocate memory for payload %d", i + BUFFER_MAX_NOMINAL);
274
275                 payload->id = i;
276                 ret = ast_data_buffer_put(buffer, i + BUFFER_MAX_NOMINAL, payload);
277                 if (ret) {
278                         ast_free(payload);
279                 }
280
281                 ast_test_validate(test, ret == 0,
282                                 "Failed to add payload %d to buffer", i + BUFFER_MAX_NOMINAL);
283         }
284
285         ast_test_validate(test, ast_data_buffer_count(buffer) == BUFFER_MAX_NOMINAL,
286                         "Buffer does not have the expected count after replacing payloads");
287
288         for (i = 1; i <= BUFFER_MAX_NOMINAL; i++) {
289                 fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, i);
290
291                 ast_test_validate(test, fetched_payload == NULL,
292                                 "Got an unexpected payload at position %d", i);
293
294                 fetched_payload = (struct mock_payload *)ast_data_buffer_get(buffer, i + BUFFER_MAX_NOMINAL);
295
296                 ast_test_validate(test, fetched_payload != NULL,
297                                 "Failed to get payload at position %d during second loop", i + BUFFER_MAX_NOMINAL);
298         }
299
300         removed_payload = (struct mock_payload *)ast_data_buffer_remove_head(buffer);
301
302         ast_test_validate(test, removed_payload != NULL,
303                         "Failed to get the payload at the HEAD of the buffer");
304
305         ast_test_validate(test, ast_data_buffer_count(buffer) == BUFFER_MAX_NOMINAL - 1,
306                         "Removing payload from HEAD of buffer did not decrease buffer size");
307
308         ast_test_validate(test, removed_payload->id == 1,
309                         "Removing payload from HEAD of buffer did not return expected payload");
310
311         ast_free(removed_payload);
312
313         removed_payload = (struct mock_payload *)ast_data_buffer_remove(buffer, BUFFER_MAX_NOMINAL * 2);
314
315         ast_test_validate(test, removed_payload != NULL,
316                         "Failed to get payload at position %d from buffer", BUFFER_MAX_NOMINAL * 2);
317
318         ast_test_validate(test, ast_data_buffer_count(buffer) == BUFFER_MAX_NOMINAL - 2,
319                         "Removing payload from buffer did not decrease buffer size");
320
321         ast_test_validate(test, removed_payload->id == BUFFER_MAX_NOMINAL,
322                         "Removing payload from buffer did not return expected payload");
323
324         return AST_TEST_PASS;
325 }
326
327 static int unload_module(void)
328 {
329         AST_TEST_UNREGISTER(buffer_create);
330         AST_TEST_UNREGISTER(buffer_put);
331         AST_TEST_UNREGISTER(buffer_resize);
332         AST_TEST_UNREGISTER(buffer_nominal);
333         return 0;
334 }
335
336 static int load_module(void)
337 {
338         AST_TEST_REGISTER(buffer_create);
339         AST_TEST_REGISTER(buffer_put);
340         AST_TEST_REGISTER(buffer_resize);
341         AST_TEST_REGISTER(buffer_nominal);
342         return AST_MODULE_LOAD_SUCCESS;
343 }
344
345 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Data buffer API test module");