Asterisk - The Open Source Telephony Project  18.5.0
test_data_buffer.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2018, Digium, Inc.
5  *
6  * Ben Ford <[email protected]>
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 Data Buffer API Unit Tests
22  *
23  * \author Ben Ford <[email protected]>
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 
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 {
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 
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 {
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 {
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 
195 
196  ast_test_validate(test, buffer != NULL,
197  "Failed to create buffer with valid arguments");
198 
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 
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 {
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 
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);
343 }
344 
345 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Data buffer API test module");
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
Data buffer containing fixed number of data payloads.
Definition: data_buffer.c:59
struct ast_data_buffer * ast_data_buffer_alloc(ast_data_buffer_free_callback free_fn, size_t size)
Allocate a data buffer.
Definition: data_buffer.c:145
void * ast_data_buffer_remove(struct ast_data_buffer *buffer, size_t pos)
Remove a data payload from the data buffer.
Definition: data_buffer.c:299
Data Buffer API.
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static int unload_module(void)
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
int ast_data_buffer_put(struct ast_data_buffer *buffer, size_t pos, void *payload)
Place a data payload at a position in the data buffer.
Definition: data_buffer.c:203
#define BUFFER_MAX_NOMINAL
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void * ast_data_buffer_get(const struct ast_data_buffer *buffer, size_t pos)
Retrieve a data payload from the data buffer.
Definition: data_buffer.c:269
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
def info(msg)
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int load_module(void)
static void ast_data_buffer_free_wrapper(struct ast_data_buffer *buffer)
size_t ast_data_buffer_count(const struct ast_data_buffer *buffer)
Return the number of payloads in a data buffer.
Definition: data_buffer.c:356
void ast_data_buffer_resize(struct ast_data_buffer *buffer, size_t size)
Resize a data buffer.
Definition: data_buffer.c:168
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
size_t ast_data_buffer_max(const struct ast_data_buffer *buffer)
Return the maximum number of payloads a data buffer can hold.
Definition: data_buffer.c:363
AST_TEST_DEFINE(buffer_create)
void ast_data_buffer_free(struct ast_data_buffer *buffer)
Free a data buffer (and all held data payloads)
Definition: data_buffer.c:338
void * ast_data_buffer_remove_head(struct ast_data_buffer *buffer)
Remove the first payload from the data buffer.
Definition: data_buffer.c:320