1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
#define SENSE 0xAB /* produces 10101011 */
static bool mem_has_bytes(const void *mem, size_t size, uint8_t b)
{
const uint8_t *bytes = mem;
unsigned int i;
for (i = 0; i < size; i++) {
if (bytes[i] != b) {
i_debug("bytes[%u] != %u", i, b);
return FALSE;
}
}
return TRUE;
}
void test_mempool_allocfree(void)
{
pool_t pool;
unsigned int i;
size_t last_alloc = 0;
size_t used = 0;
size_t count = 0;
void *mem = NULL;
test_begin("mempool_allocfree");
pool = pool_allocfree_create("test");
for(i = 0; i <= 1000; i++) {
/* release previous allocation */
if ((i % 3) == 0) {
if (mem != NULL) {
test_assert_idx(mem_has_bytes(mem, last_alloc, SENSE), i);
used -= last_alloc;
count--;
}
last_alloc = 0;
p_free(pool, mem);
/* grow previous allocation */
} else if ((i % 5) == 0) {
if (mem != NULL)
used -= last_alloc;
else
count++;
mem = p_realloc(pool, mem, last_alloc, i*2);
if (last_alloc > 0)
test_assert_idx(mem_has_bytes(mem, last_alloc, SENSE), i);
memset(mem, SENSE, i*2);
last_alloc = i*2;
used += i*2;
/* shrink previous allocation */
} else if ((i % 7) == 0) {
if (mem != NULL)
used -= last_alloc;
else
count++;
mem = p_realloc(pool, mem, last_alloc, i-2);
if (last_alloc > 0)
test_assert_idx(mem_has_bytes(mem, i-2, SENSE), i);
memset(mem, SENSE, i-2);
last_alloc = i-2;
used += i-2;
/* allocate some memory */
} else {
mem = p_malloc(pool, i);
/* fill it with sense marker */
memset(mem, SENSE, i);
used += i;
count++;
last_alloc = i;
}
}
test_assert(pool_allocfree_get_total_used_size(pool) == used);
pool_unref(&pool);
/* make sure realloc works correctly */
pool = pool_allocfree_create("test");
mem = NULL;
for(i = 1; i < 1000; i++) {
mem = p_realloc(pool, mem, i-1, i);
test_assert_idx(mem_has_bytes(mem, i-1, 0xde), i);
memset(mem, 0xde, i);
}
pool_unref(&pool);
test_end();
}
enum fatal_test_state fatal_mempool_allocfree(unsigned int stage)
{
static pool_t pool;
if (pool == NULL && stage != 0)
return FATAL_TEST_FAILURE;
switch(stage) {
case 0: /* forbidden size */
test_begin("fatal_mempool_allocfree");
pool = pool_allocfree_create("fatal");
test_expect_fatal_string("Trying to allocate 0 bytes");
(void)p_malloc(pool, 0);
return FATAL_TEST_FAILURE;
case 1: /* logically impossible size */
test_expect_fatal_string("Trying to allocate");
(void)p_malloc(pool, POOL_MAX_ALLOC_SIZE + 1ULL);
return FATAL_TEST_FAILURE;
#ifdef _LP64 /* malloc(POOL_MAX_ALLOC_SIZE) may succeed with 32bit */
case 2: /* physically impossible size */
test_expect_fatal_string("Out of memory");
(void)p_malloc(pool, POOL_MAX_ALLOC_SIZE);
return FATAL_TEST_FAILURE;
#endif
/* Continue with other tests as follows:
case 3:
something_fatal();
return FATAL_TEST_FAILURE;
*/
}
/* Either our tests have finished, or the test suite has got confused. */
pool_unref(&pool);
test_end();
return FATAL_TEST_FINISHED;
}
|