1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/stack_tests.c Mon Jul 28 14:36:25 2014 +0200 1.3 @@ -0,0 +1,209 @@ 1.4 +/* 1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 + * 1.7 + * Copyright 2014 Olaf Wintermann. All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 1.15 + * 2. Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in the 1.17 + * documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 + * POSSIBILITY OF SUCH DAMAGE. 1.30 + */ 1.31 + 1.32 +#include "stack_tests.h" 1.33 + 1.34 +#define test_ucx_stack_before \ 1.35 + char space[100]; \ 1.36 + UcxStack stack; \ 1.37 + ucx_stack_init(&stack, space, 100) \ 1.38 + 1.39 +UCX_TEST(test_ucx_stack_init) { 1.40 + 1.41 + test_ucx_stack_before; 1.42 + 1.43 + UCX_TEST_BEGIN 1.44 + 1.45 + UCX_TEST_ASSERT( 1.46 + stack.allocator.malloc == (ucx_allocator_malloc) ucx_stack_malloc && 1.47 + stack.allocator.calloc == (ucx_allocator_calloc) ucx_stack_calloc && 1.48 + stack.allocator.realloc == (ucx_allocator_realloc) ucx_stack_realloc && 1.49 + stack.allocator.free == (ucx_allocator_free) ucx_stack_free && 1.50 + stack.allocator.pool == &stack, 1.51 + "allocator not properly set"); 1.52 + 1.53 + UCX_TEST_ASSERT(!stack.top && stack.space == space 1.54 + && stack.size == 100 - 100 % sizeof(void*), 1.55 + "struct fields not properly set"); 1.56 + 1.57 + UCX_TEST_END 1.58 +} 1.59 + 1.60 +UCX_TEST(test_ucx_stack_malloc) { 1.61 + 1.62 + test_ucx_stack_before; 1.63 + 1.64 + const size_t metasize = sizeof(struct ucx_stack_metadata); 1.65 + 1.66 + 1.67 + char* first = (char*) ucx_stack_malloc(&stack, 30); 1.68 + char* second = (char*) ucx_stack_malloc(&stack, 30); 1.69 + char* full = (char*) ucx_stack_malloc(&stack, 30); 1.70 + 1.71 + memcpy(first, "012345678901234567890123456789", 30); 1.72 + memcpy(second, "abcdefghijklmnopqrstuvwxyzABCD", 30); 1.73 + 1.74 + UCX_TEST_BEGIN 1.75 + 1.76 + UCX_TEST_ASSERT(!memcmp(space + metasize, 1.77 + "012345678901234567890123456789", 30), "first element corrupted"); 1.78 + UCX_TEST_ASSERT(!memcmp(space + 32+2*metasize, 1.79 + "abcdefghijklmnopqrstuvwxyzABCD", 30), "first element corrupted"); 1.80 + 1.81 + UCX_TEST_ASSERT(!full, "stack can be overflowed"); 1.82 + UCX_TEST_ASSERT(stack.top == space + 32 + 2*metasize, "wrong top pointer"); 1.83 + 1.84 + if (3*metasize < 32) { 1.85 + UCX_TEST_ASSERT(ucx_stack_avail(&stack) == 32-3*metasize, 1.86 + "wrong remaining available memory"); 1.87 + } else { 1.88 + UCX_TEST_ASSERT(ucx_stack_avail(&stack) == 0, 1.89 + "wrong remaining available memory"); 1.90 + } 1.91 + 1.92 + UCX_TEST_END 1.93 +} 1.94 + 1.95 +UCX_TEST(test_ucx_stack_calloc) { 1.96 + 1.97 + test_ucx_stack_before; 1.98 + 1.99 + char zeros[100]; 1.100 + memset(zeros, 0, 100); 1.101 + memset(space, 32, 100); 1.102 + ucx_stack_calloc(&stack, 4, sizeof(int)); 1.103 + 1.104 + UCX_TEST_BEGIN 1.105 + 1.106 + UCX_TEST_ASSERT(!memcmp(space+sizeof(struct ucx_stack_metadata), 1.107 + zeros, 4*sizeof(int)), "memory not nulled"); 1.108 + UCX_TEST_ASSERT(!memcmp(space+sizeof(struct ucx_stack_metadata) 1.109 + +4*sizeof(int), " ", 10), "too much memory nulled"); 1.110 + 1.111 + UCX_TEST_END 1.112 +} 1.113 + 1.114 +UCX_TEST(test_ucx_stack_free) { 1.115 + 1.116 + test_ucx_stack_before; 1.117 + 1.118 + void *fst = ucx_stack_malloc(&stack, 10); 1.119 + void *snd = ucx_stack_malloc(&stack, 10); 1.120 + void *thrd = ucx_stack_malloc(&stack, 10); 1.121 + 1.122 + UCX_TEST_BEGIN 1.123 + 1.124 + UCX_TEST_ASSERT(stack.top == thrd, "wrong stack"); 1.125 + UCX_TEST_ASSERT(((struct ucx_stack_metadata*) thrd - 1)->prev == snd, 1.126 + "wrong thrd prev pointer before free"); 1.127 + 1.128 + ucx_stack_free(&stack, snd); 1.129 + 1.130 + UCX_TEST_ASSERT(((struct ucx_stack_metadata*) thrd - 1)->prev == fst, 1.131 + "wrong thrd prev pointer after freeing snd"); 1.132 + UCX_TEST_ASSERT(stack.top == thrd, "wrong top after freeing snd"); 1.133 + 1.134 + ucx_stack_free(&stack, thrd); 1.135 + 1.136 + UCX_TEST_ASSERT(stack.top == fst, "wrong top after freeing thrd"); 1.137 + 1.138 + UCX_TEST_END 1.139 +} 1.140 + 1.141 +UCX_TEST(test_ucx_stack_realloc) { 1.142 + 1.143 + test_ucx_stack_before; 1.144 + 1.145 + void *fst = ucx_stack_malloc(&stack, 10); 1.146 + void *snd = ucx_stack_malloc(&stack, 10); 1.147 + 1.148 + UCX_TEST_BEGIN 1.149 + 1.150 + void *nfst = ucx_stack_realloc(&stack, fst, 16); 1.151 + UCX_TEST_ASSERT(nfst == fst, "unnecessary move on reallocation"); 1.152 + UCX_TEST_ASSERT(((struct ucx_stack_metadata*)fst - 1)->size == 16, 1.153 + "wrong size after reallocation"); 1.154 + 1.155 + void *nsnd = ucx_stack_realloc(&stack, snd, 30); 1.156 + UCX_TEST_ASSERT(nsnd == snd, "unnecessary move on top reallocation"); 1.157 + UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 30, 1.158 + "wrong size after top reallocation"); 1.159 + 1.160 + nsnd = ucx_stack_realloc(&stack, snd, 5); 1.161 + UCX_TEST_ASSERT(nsnd == snd, "unnecessary move on top shrink"); 1.162 + UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 5, 1.163 + "wrong size after top shrink"); 1.164 + UCX_TEST_ASSERT(ucx_stack_avail(&stack) == 1.165 + 72-3*sizeof(struct ucx_stack_metadata), "wrong size after top shrink"); 1.166 + 1.167 + nfst = ucx_stack_realloc(&stack, fst, 24); 1.168 + UCX_TEST_ASSERT(nfst != fst, "missing move on huge reallocation"); 1.169 + UCX_TEST_ASSERT(stack.top == nfst, "wrong top after huge reallocation"); 1.170 + UCX_TEST_ASSERT(ucx_stack_topsize(&stack) == 24, 1.171 + "wrong size after huge reallocation"); 1.172 + UCX_TEST_ASSERT(!((struct ucx_stack_metadata*)snd - 1)->prev, 1.173 + "element not freed after huge reallocation"); 1.174 + 1.175 + UCX_TEST_END 1.176 +} 1.177 + 1.178 +UCX_TEST(test_ucx_stack_pop) { 1.179 + 1.180 + test_ucx_stack_before; 1.181 + memset(space, 32, 100); 1.182 + 1.183 + void *fst = ucx_stack_malloc(&stack, 10); 1.184 + void *snd = ucx_stack_malloc(&stack, 10); 1.185 + ucx_stack_malloc(&stack, 10); 1.186 + 1.187 + char buf[16]; 1.188 + 1.189 + UCX_TEST_BEGIN 1.190 + 1.191 + memset(buf, '0', 16); 1.192 + ucx_stack_pop(&stack, buf); 1.193 + UCX_TEST_ASSERT(memcmp(buf, " 000000", 16) == 0, 1.194 + "popped wrong content"); 1.195 + UCX_TEST_ASSERT(stack.top == snd, "wrong top after pop"); 1.196 + 1.197 + memset(buf, '0', 16); 1.198 + ucx_stack_popn(&stack, buf, 5); 1.199 + UCX_TEST_ASSERT(memcmp(buf, " 00000000000", 16) == 0, 1.200 + "n-popped wrong content"); 1.201 + UCX_TEST_ASSERT(stack.top == fst, "wrong top after pop"); 1.202 + 1.203 + ucx_stack_pop(&stack, buf); 1.204 + UCX_TEST_ASSERT(!stack.top, "top not NULL after last pop"); 1.205 + 1.206 + memset(buf, '0', 16); 1.207 + ucx_stack_pop(&stack, buf); 1.208 + UCX_TEST_ASSERT(memcmp(buf, "0000000000000000", 16) == 0, 1.209 + "content not unchanged after empty pop"); 1.210 + 1.211 + UCX_TEST_END 1.212 +}