OpenVPN
test_buffer.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2016-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #include <setjmp.h>
33 #include <cmocka.h>
34 
35 #include "buffer.h"
36 #include "buffer.c"
37 
38 static void
39 test_buffer_strprefix(void **state)
40 {
41  assert_true(strprefix("123456", "123456"));
42  assert_true(strprefix("123456", "123"));
43  assert_true(strprefix("123456", ""));
44  assert_false(strprefix("123456", "456"));
45  assert_false(strprefix("12", "123"));
46 }
47 
48 #define testsep ","
49 #define testnosep ""
50 #define teststr1 "one"
51 #define teststr2 "two"
52 #define teststr3 "three"
53 #define teststr4 "four"
54 
55 #define assert_buf_equals_str(buf, str) \
56  assert_int_equal(BLEN(buf), strlen(str)); \
57  assert_memory_equal(BPTR(buf), str, BLEN(buf));
58 
60  struct buffer_list *empty;
64 };
65 
66 static int
68 {
69  struct test_buffer_list_aggregate_ctx *ctx = calloc(1, sizeof(*ctx));
70  ctx->empty = buffer_list_new();
71 
76 
80 
82  uint8_t data = 0;
83  buffer_list_push_data(ctx->empty_buffers, &data, 0);
84  buffer_list_push_data(ctx->empty_buffers, &data, 0);
85 
86  *state = ctx;
87  return 0;
88 }
89 
90 static int
92 {
93  struct test_buffer_list_aggregate_ctx *ctx = *state;
94 
95  buffer_list_free(ctx->empty);
99  free(ctx);
100  return 0;
101 }
102 
103 static void
105 {
106  struct test_buffer_list_aggregate_ctx *ctx = *state;
107 
108  /* aggregating an empty buffer list results in an empty buffer list */
110  assert_null(ctx->empty->head);
111 }
112 
113 static void
115 {
116  struct test_buffer_list_aggregate_ctx *ctx = *state;
117 
118  /* With a max length of 2, no aggregation should take place */
120  assert_int_equal(ctx->one_two_three->size, 3);
121  struct buffer *buf = buffer_list_peek(ctx->one_two_three);
123 }
124 
125 static void
127 {
128  struct test_buffer_list_aggregate_ctx *ctx = *state;
129  const char *expected = teststr1 testsep teststr2 testsep;
130 
131  /* Aggregate the first two elements
132  * (add 1 to max_len to test if "three" is not sneaked in too)
133  */
134  buffer_list_aggregate_separator(ctx->one_two_three, strlen(expected) + 1,
135  testsep);
136  assert_int_equal(ctx->one_two_three->size, 2);
137  struct buffer *buf = buffer_list_peek(ctx->one_two_three);
138  assert_buf_equals_str(buf, expected);
139 }
140 
141 static void
143 {
144  struct test_buffer_list_aggregate_ctx *ctx = *state;
145 
146  /* Aggregate all */
148  assert_int_equal(ctx->one_two_three->size, 1);
149  struct buffer *buf = buffer_list_peek(ctx->one_two_three);
152 }
153 
154 static void
156 {
157  struct test_buffer_list_aggregate_ctx *ctx = *state;
158 
159  /* Aggregate all */
161  assert_int_equal(ctx->one_two_three->size, 1);
162  struct buffer *buf = buffer_list_peek(ctx->one_two_three);
164 }
165 
166 static void
168 {
169  struct test_buffer_list_aggregate_ctx *ctx = *state;
170  struct buffer_list *bl_zerolen = ctx->zero_length_strings;
171 
172  /* Aggregate all */
173  buffer_list_aggregate_separator(bl_zerolen, 1<<16, testnosep);
174  assert_int_equal(bl_zerolen->size, 1);
175  struct buffer *buf = buffer_list_peek(bl_zerolen);
176  assert_buf_equals_str(buf, "");
177 }
178 
179 static void
181 {
182  struct test_buffer_list_aggregate_ctx *ctx = *state;
183  struct buffer_list *bl_emptybuffers = ctx->empty_buffers;
184 
185  /* Aggregate all */
186  buffer_list_aggregate_separator(bl_emptybuffers, 1<<16, testnosep);
187  assert_int_equal(bl_emptybuffers->size, 1);
188  struct buffer *buf = buffer_list_peek(bl_emptybuffers);
189  assert_int_equal(BLEN(buf), 0);
190 }
191 
192 static void
194 {
195  struct gc_arena gc = gc_new();
196  struct buffer buf = alloc_buf_gc(1024, &gc);
197 
198  assert_ptr_equal(gc.list + 1, buf.data);
199  free_buf_gc(&buf, &gc);
200  assert_null(gc.list);
201 
202  gc_free(&gc);
203 }
204 
205 static void
207 {
208  struct gc_arena gc = gc_new();
209  struct buffer buf1 = alloc_buf_gc(1024, &gc);
210  struct buffer buf2 = alloc_buf_gc(1024, &gc);
211  struct buffer buf3 = alloc_buf_gc(1024, &gc);
212 
213  struct gc_entry *e;
214 
215  e = gc.list;
216 
217  assert_ptr_equal(e + 1, buf3.data);
218  assert_ptr_equal(e->next + 1, buf2.data);
219  assert_ptr_equal(e->next->next + 1, buf1.data);
220 
221  free_buf_gc(&buf2, &gc);
222 
223  assert_non_null(gc.list);
224 
225  while (e)
226  {
227  assert_ptr_not_equal(e + 1, buf2.data);
228  e = e->next;
229  }
230 
231  gc_free(&gc);
232 }
233 
234 int
235 main(void)
236 {
237  const struct CMUnitTest tests[] = {
238  cmocka_unit_test(test_buffer_strprefix),
239  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_empty,
242  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_noop,
245  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_two,
248  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_all,
251  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_nosep,
254  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_zerolen,
257  cmocka_unit_test_setup_teardown(test_buffer_list_aggregate_separator_emptybuffers,
260  cmocka_unit_test(test_buffer_free_gc_one),
261  cmocka_unit_test(test_buffer_free_gc_two),
262  };
263 
264  return cmocka_run_group_tests_name("buffer", tests, NULL, NULL);
265 }
gc_arena::list
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition: buffer.h:118
test_buffer_list_aggregate_separator_all
static void test_buffer_list_aggregate_separator_all(void **state)
Definition: test_buffer.c:142
test_buffer_list_aggregate_ctx::empty_buffers
struct buffer_list * empty_buffers
Definition: test_buffer.c:63
test_buffer_free_gc_two
static void test_buffer_free_gc_two(void **state)
Definition: test_buffer.c:206
assert_buf_equals_str
#define assert_buf_equals_str(buf, str)
Definition: test_buffer.c:55
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:998
gc_entry::next
struct gc_entry * next
Pointer to the next item in the linked list.
Definition: buffer.h:89
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:90
config-msvc.h
gc_entry
Garbage collection entry for one dynamically allocated block of memory.
Definition: buffer.h:87
buffer_list_peek
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition: buffer.c:1255
buffer_list_aggregate_separator
void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition: buffer.c:1268
test_buffer_list_aggregate_ctx::empty
struct buffer_list * empty
Definition: test_buffer.c:60
testnosep
#define testnosep
Definition: test_buffer.c:49
test_buffer_list_aggregate_ctx
Definition: test_buffer.c:59
test_buffer_list_aggregate_separator_zerolen
static void test_buffer_list_aggregate_separator_zerolen(void **state)
Definition: test_buffer.c:167
buffer_list_push_data
struct buffer_entry * buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size)
Allocates and appends a new buffer containing data of length size.
Definition: buffer.c:1228
test_buffer_strprefix
static void test_buffer_strprefix(void **state)
Definition: test_buffer.c:39
BLEN
#define BLEN(buf)
Definition: buffer.h:127
test_buffer_list_aggregate_separator_emptybuffers
static void test_buffer_list_aggregate_separator_emptybuffers(void **state)
Definition: test_buffer.c:180
buffer_list_push
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
Definition: buffer.c:1214
teststr3
#define teststr3
Definition: test_buffer.c:52
test_buffer_list_aggregate_ctx::zero_length_strings
struct buffer_list * zero_length_strings
Definition: test_buffer.c:62
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
buffer_list::size
int size
Definition: buffer.h:1097
buffer_list_new
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
Definition: buffer.c:1174
buffer.h
syshead.h
testsep
#define testsep
Definition: test_buffer.c:48
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
free_buf_gc
static void free_buf_gc(struct buffer *buf, struct gc_arena *gc)
Definition: buffer.c:192
test_buffer_free_gc_one
static void test_buffer_free_gc_one(void **state)
Definition: test_buffer.c:193
main
int main(void)
Definition: test_buffer.c:235
strprefix
static bool strprefix(const char *str, const char *prefix)
Return true iff str starts with prefix.
Definition: buffer.h:945
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1006
test_buffer_list_aggregate_separator_nosep
static void test_buffer_list_aggregate_separator_nosep(void **state)
Definition: test_buffer.c:155
test_buffer_list_aggregate_separator_empty
static void test_buffer_list_aggregate_separator_empty(void **state)
Definition: test_buffer.c:104
config.h
buffer_list_free
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition: buffer.c:1183
teststr2
#define teststr2
Definition: test_buffer.c:51
test_buffer_list_aggregate_ctx::one_two_three
struct buffer_list * one_two_three
Definition: test_buffer.c:61
teststr1
#define teststr1
Definition: test_buffer.c:50
test_buffer_list_setup
static int test_buffer_list_setup(void **state)
Definition: test_buffer.c:67
buffer_list
Definition: buffer.h:1093
test_buffer_list_aggregate_separator_noop
static void test_buffer_list_aggregate_separator_noop(void **state)
Definition: test_buffer.c:114
test_buffer_list_teardown
static int test_buffer_list_teardown(void **state)
Definition: test_buffer.c:91
buffer_list::head
struct buffer_entry * head
Definition: buffer.h:1095
buffer.c
test_buffer_list_aggregate_separator_two
static void test_buffer_list_aggregate_separator_two(void **state)
Definition: test_buffer.c:126
buffer::data
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68