test/stack_tests.c

changeset 185
a48428642b4e
parent 177
11ad03783baf
child 187
7d49f179cc25
     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 +}

mercurial