blob: 8ed5faf8f229e00508f000e324da77ae1d8eaf4b [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono5dcb38d2005-11-21 01:55:47 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/pool.h>
Benny Prijono83217fa2007-02-16 21:44:36 +000020#include <pj/pool_buf.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000021#include <pj/rand.h>
22#include <pj/log.h>
Benny Prijono83217fa2007-02-16 21:44:36 +000023#include <pj/except.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000024#include "test.h"
25
26/**
27 * \page page_pjlib_pool_test Test: Pool
28 *
29 * This file provides implementation of \b pool_test(). It tests the
30 * functionality of the memory pool.
31 *
32 *
33 * This file is <b>pjlib-test/pool.c</b>
34 *
35 * \include pjlib-test/pool.c
36 */
37
38
39#if INCLUDE_POOL_TEST
40
41#define SIZE 4096
42
43/* Normally we should throw exception when memory alloc fails.
44 * Here we do nothing so that the flow will go back to original caller,
45 * which will test the result using NULL comparison. Normally caller will
46 * catch the exception instead of checking for NULLs.
47 */
48static void null_callback(pj_pool_t *pool, pj_size_t size)
49{
50 PJ_UNUSED_ARG(pool);
51 PJ_UNUSED_ARG(size);
52}
53
54#define GET_FREE(p) (pj_pool_get_capacity(p)-pj_pool_get_used_size(p))
55
56/* Test that the capacity and used size reported by the pool is correct.
57 */
58static int capacity_test(void)
59{
60 pj_pool_t *pool = pj_pool_create(mem, NULL, SIZE, 0, &null_callback);
61 pj_size_t freesize;
62
63 PJ_LOG(3,("test", "...capacity_test()"));
64
65 if (!pool)
66 return -200;
67
68 freesize = GET_FREE(pool);
69
70 if (pj_pool_alloc(pool, freesize) == NULL) {
71 PJ_LOG(3,("test", "...error: wrong freesize %u reported",
72 freesize));
73 pj_pool_release(pool);
74 return -210;
75 }
76
77 pj_pool_release(pool);
78 return 0;
79}
80
81/* Test function to drain the pool's space.
82 */
83static int drain_test(pj_size_t size, pj_size_t increment)
84{
85 pj_pool_t *pool = pj_pool_create(mem, NULL, size, increment,
86 &null_callback);
87 pj_size_t freesize;
88 void *p;
89 int status = 0;
90
91 PJ_LOG(3,("test", "...drain_test(%d,%d)", size, increment));
92
93 if (!pool)
94 return -10;
95
96 /* Get free size */
97 freesize = GET_FREE(pool);
98 if (freesize < 1) {
99 status=-15;
100 goto on_error;
101 }
102
103 /* Drain the pool until there's nothing left. */
104 while (freesize > 0) {
105 int size;
106
107 if (freesize > 255)
Nanang Izzuddin9375aca2008-04-23 14:35:24 +0000108 size = ((pj_rand() & 0x000000FF) + PJ_POOL_ALIGNMENT) &
109 ~(PJ_POOL_ALIGNMENT - 1);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000110 else
111 size = freesize;
112
113 p = pj_pool_alloc(pool, size);
114 if (!p) {
115 status=-20; goto on_error;
116 }
117
118 freesize -= size;
119 }
120
121 /* Check that capacity is zero. */
122 if (GET_FREE(pool) != 0) {
123 PJ_LOG(3,("test", "....error: returned free=%u (expecting 0)",
124 GET_FREE(pool)));
125 status=-30; goto on_error;
126 }
127
128 /* Try to allocate once more */
129 p = pj_pool_alloc(pool, 257);
130 if (!p) {
131 status=-40; goto on_error;
132 }
133
134 /* Check that capacity is NOT zero. */
135 if (GET_FREE(pool) == 0) {
136 status=-50; goto on_error;
137 }
138
139
140on_error:
141 pj_pool_release(pool);
142 return status;
143}
144
Benny Prijono83217fa2007-02-16 21:44:36 +0000145/* Test the buffer based pool */
146static int pool_buf_test(void)
147{
148 enum { STATIC_BUF_SIZE = 40 };
149 /* 16 is the internal struct in pool_buf */
150 static char buf[ STATIC_BUF_SIZE + sizeof(pj_pool_t) +
151 sizeof(pj_pool_block) + 16];
152 pj_pool_t *pool;
153 void *p;
154 PJ_USE_EXCEPTION;
155
156 PJ_LOG(3,("test", "...pool_buf test"));
157
158 pool = pj_pool_create_on_buf("no name", buf, sizeof(buf));
159 if (!pool)
160 return -70;
161
162 /* Drain the pool */
163 PJ_TRY {
164 if ((p=pj_pool_alloc(pool, STATIC_BUF_SIZE/2)) == NULL)
165 return -75;
166
167 if ((p=pj_pool_alloc(pool, STATIC_BUF_SIZE/2)) == NULL)
168 return -76;
169 }
170 PJ_CATCH_ANY {
171 return -77;
172 }
173 PJ_END;
174
175 /* On the next alloc, exception should be thrown */
176 PJ_TRY {
177 p = pj_pool_alloc(pool, STATIC_BUF_SIZE);
178 if (p != NULL) {
179 /* This is unexpected, the alloc should fail */
180 return -78;
181 }
182 }
183 PJ_CATCH_ANY {
184 /* This is the expected result */
185 }
186 PJ_END;
187
188 /* Done */
189 return 0;
190}
191
192
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000193int pool_test(void)
194{
195 enum { LOOP = 2 };
196 int loop;
197 int rc;
198
199 rc = capacity_test();
200 if (rc) return rc;
201
202 for (loop=0; loop<LOOP; ++loop) {
203 /* Test that the pool should grow automaticly. */
204 rc = drain_test(SIZE, SIZE);
205 if (rc != 0) return rc;
206
207 /* Test situation where pool is not allowed to grow.
208 * We expect the test to return correct error.
209 */
210 rc = drain_test(SIZE, 0);
211 if (rc != -40) return rc;
212 }
213
Benny Prijono83217fa2007-02-16 21:44:36 +0000214 rc = pool_buf_test();
215 if (rc != 0)
216 return rc;
217
218
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000219 return 0;
220}
221
222#else
223/* To prevent warning about "translation unit is empty"
224 * when this test is disabled.
225 */
226int dummy_pool_test;
227#endif /* INCLUDE_POOL_TEST */
228