test/stack_tests.c

changeset 390
d345541018fa
parent 259
2f5dea574a75
equal deleted inserted replaced
389:92e482410453 390:d345541018fa
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "stack_tests.h"
30
31 #define test_ucx_stack_before \
32 char space[99]; \
33 UcxStack stack; \
34 ucx_stack_init(&stack, space, 99) \
35
36 UCX_TEST(test_ucx_stack_init) {
37
38 test_ucx_stack_before;
39
40 UCX_TEST_BEGIN
41
42 UCX_TEST_ASSERT(
43 stack.allocator.malloc == (ucx_allocator_malloc) ucx_stack_malloc &&
44 stack.allocator.calloc == (ucx_allocator_calloc) ucx_stack_calloc &&
45 stack.allocator.realloc == (ucx_allocator_realloc) ucx_stack_realloc &&
46 stack.allocator.free == (ucx_allocator_free) ucx_stack_free &&
47 stack.allocator.pool == &stack,
48 "allocator not properly set");
49
50 UCX_TEST_ASSERT(!stack.top && stack.space == space
51 && stack.size == 99 - 99 % sizeof(void*),
52 "struct fields not properly set");
53
54 UCX_TEST_END
55 }
56
57 UCX_TEST(test_ucx_stack_malloc) {
58
59 test_ucx_stack_before;
60
61 const size_t metasize = sizeof(struct ucx_stack_metadata);
62
63
64 char* first = (char*) ucx_stack_malloc(&stack, 30);
65 char* second = (char*) ucx_stack_malloc(&stack, 30);
66 char* full = (char*) ucx_stack_malloc(&stack, 30);
67
68 memcpy(first, "012345678901234567890123456789", 30);
69 memcpy(second, "abcdefghijklmnopqrstuvwxyzABCD", 30);
70
71 UCX_TEST_BEGIN
72
73 UCX_TEST_ASSERT(!memcmp(space + metasize,
74 "012345678901234567890123456789", 30), "first element corrupted");
75 UCX_TEST_ASSERT(!memcmp(space + 32+2*metasize,
76 "abcdefghijklmnopqrstuvwxyzABCD", 30), "first element corrupted");
77
78 UCX_TEST_ASSERT(!full, "stack can be overflowed");
79 UCX_TEST_ASSERT(stack.top == space + 32 + 2*metasize, "wrong top pointer");
80
81 if (3*metasize < 32) {
82 UCX_TEST_ASSERT(ucx_stack_avail(&stack) == 32-3*metasize,
83 "wrong remaining available memory");
84 } else {
85 UCX_TEST_ASSERT(ucx_stack_avail(&stack) == 0,
86 "wrong remaining available memory");
87 }
88
89 UCX_TEST_END
90 }
91
92 UCX_TEST(test_ucx_stack_calloc) {
93
94 test_ucx_stack_before;
95
96 char zeros[99];
97 memset(zeros, 0, 99);
98 memset(space, 32, 99);
99 ucx_stack_calloc(&stack, 4, sizeof(int));
100
101 UCX_TEST_BEGIN
102
103 UCX_TEST_ASSERT(!memcmp(space+sizeof(struct ucx_stack_metadata),
104 zeros, 4*sizeof(int)), "memory not nulled");
105 UCX_TEST_ASSERT(!memcmp(space+sizeof(struct ucx_stack_metadata)
106 +4*sizeof(int), " ", 10), "too much memory nulled");
107
108 UCX_TEST_END
109 }
110
111 UCX_TEST(test_ucx_stack_free) {
112
113 test_ucx_stack_before;
114
115 void *fst = ucx_stack_malloc(&stack, 10);
116 void *snd = ucx_stack_malloc(&stack, 10);
117 void *thrd = ucx_stack_malloc(&stack, 10);
118
119 UCX_TEST_BEGIN
120
121 UCX_TEST_ASSERT(stack.top == thrd, "wrong stack");
122 UCX_TEST_ASSERT(((struct ucx_stack_metadata*) thrd - 1)->prev == snd,
123 "wrong thrd prev pointer before free");
124
125 ucx_stack_free(&stack, snd);
126
127 UCX_TEST_ASSERT(((struct ucx_stack_metadata*) thrd - 1)->prev == fst,
128 "wrong thrd prev pointer after freeing snd");
129 UCX_TEST_ASSERT(stack.top == thrd, "wrong top after freeing snd");
130
131 ucx_stack_free(&stack, thrd);
132
133 UCX_TEST_ASSERT(stack.top == fst, "wrong top after freeing thrd");
134
135 UCX_TEST_END
136 }
137
138 UCX_TEST(test_ucx_stack_realloc) {
139
140 test_ucx_stack_before;
141
142 void *fst = ucx_stack_malloc(&stack, 14);
143 void *snd = ucx_stack_malloc(&stack, 10);
144
145 UCX_TEST_BEGIN
146
147 void *nfst = ucx_stack_realloc(&stack, fst, 16);
148 UCX_TEST_ASSERT(nfst == fst, "unnecessary move on reallocation");
149 UCX_TEST_ASSERT(((struct ucx_stack_metadata*)fst - 1)->size == 16,
150 "wrong size after reallocation");
151
152 void *nsnd = ucx_stack_realloc(&stack, snd, 30);
153 UCX_TEST_ASSERT(nsnd == snd, "unnecessary move on top reallocation");
154 UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 30,
155 "wrong size after top reallocation");
156
157 nsnd = ucx_stack_realloc(&stack, snd, 5);
158 UCX_TEST_ASSERT(nsnd == snd, "unnecessary move on top shrink");
159 UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 5,
160 "wrong size after top shrink");
161 UCX_TEST_ASSERT(ucx_stack_avail(&stack) ==
162 72-3*sizeof(struct ucx_stack_metadata), "wrong size after top shrink");
163
164 nfst = ucx_stack_realloc(&stack, fst, 24);
165 UCX_TEST_ASSERT(nfst != fst, "missing move on huge reallocation");
166 UCX_TEST_ASSERT(stack.top == nfst, "wrong top after huge reallocation");
167 UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 24,
168 "wrong size after huge reallocation");
169 UCX_TEST_ASSERT(!((struct ucx_stack_metadata*)snd - 1)->prev,
170 "element not freed after huge reallocation");
171
172 UCX_TEST_END
173 }
174
175 UCX_TEST(test_ucx_stack_pop) {
176
177 test_ucx_stack_before;
178 memset(space, 32, 99);
179
180 void *fst = ucx_stack_malloc(&stack, 10);
181 void *snd = ucx_stack_malloc(&stack, 10);
182 ucx_stack_malloc(&stack, 10);
183
184 char buf[16];
185
186 UCX_TEST_BEGIN
187
188 memset(buf, '0', 16);
189 ucx_stack_pop(&stack, buf);
190 UCX_TEST_ASSERT(memcmp(buf, " 000000", 16) == 0,
191 "popped wrong content");
192 UCX_TEST_ASSERT(stack.top == snd, "wrong top after pop");
193
194 memset(buf, '0', 16);
195 ucx_stack_popn(&stack, buf, 5);
196 UCX_TEST_ASSERT(memcmp(buf, " 00000000000", 16) == 0,
197 "n-popped wrong content");
198 UCX_TEST_ASSERT(stack.top == fst, "wrong top after pop");
199
200 ucx_stack_pop(&stack, buf);
201 UCX_TEST_ASSERT(!stack.top, "top not NULL after last pop");
202
203 memset(buf, '0', 16);
204 ucx_stack_pop(&stack, buf);
205 UCX_TEST_ASSERT(memcmp(buf, "0000000000000000", 16) == 0,
206 "content not unchanged after empty pop");
207
208 UCX_TEST_END
209 }

mercurial