Hardened mint test lib
[minor-tree:mint.git] / tests / mint_tests.c
1 /* mint_tests.c - some library test functions
2  *
3  * Copyright (C) 2004 Yann Droneaud <ydroneaud@meuh.org>.
4  *
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, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * 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 Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  */
20
21 #include <stdio.h>
22
23 #include <linux/mint.h>
24
25
26 #define DEBUG 1
27 #include "mint_tests.h"
28
29 void
30 print_tree(struct mint **tree)
31 {
32   printf(" tree = %p", *tree);
33     
34   if (MINT_EMPTY(tree))
35     printf(" EMPTY");
36
37   printf(" used: %d, free %d", 
38           MINT_COUNT(tree), MINT_FREE(tree));
39
40   if (!MINT_EMPTY(tree))
41     printf(" min: %u, max %u", MINT_MIN(tree), MINT_MAX(tree));
42
43   printf("\n");
44
45 }
46
47 void 
48 node_dump(const char * function, int line, 
49           const char *name, struct mint *node)
50 {
51   int i;
52
53   fflush(stdout);
54
55   printf("%s():%d  %s: %p  ", function, line, name, node);
56
57   if (node == NULL) {
58       printf("\n");
59       return;
60   }
61
62   printf("level: %d prefix: 0x%04x (%d)", 
63          node->mint_level,
64          node->mint_prefix, node->mint_prefix << MINT_BIT_SHIFT);
65
66   printf(" tree count: %d min: %d max: %d\n",
67          node->mint_tree_count,
68          node->mint_min,
69          node->mint_max );
70
71   printf("%s():%d  %s: %p  ", function, line, name, node);
72
73   printf("count: %d allocated: 0x%08x free: 0x%08x\n", 
74          node->mint_count,
75          node->mint_alloc_bitmap,
76          node->mint_free_bitmap);
77
78   printf("%s():%d  %s: %p  ", function, line, name, node);
79
80   for(i = 0; i < 32; i++)  {
81     if (node->mint_alloc_bitmap & (1 << i))
82       if (node->mint_level == 3) {
83         printf(" %u", (node->mint_prefix << MINT_BIT_SHIFT) | i);
84       } else {
85         printf(" %p", node->mint_ptr[i]);
86       }
87     else
88       printf(" ()");
89   }
90
91   printf("\n");
92
93   fflush(stdout);
94 }
95
96 int
97 node_check(struct mint *node)
98 {
99   int i;
100
101   int err = 0;
102
103   __u16 prefix;
104
105   int first;
106   int last;
107
108   int offset;
109
110   int count;
111
112   if (node == NULL) {
113     printf("FATAL, node == NULL , leaving\n");
114     return 1;
115   }
116
117   /* valid levels are [0..3] */
118   if (node->mint_level >= MINT_MAX_DEEP) {
119     printf("incorrect level\n");
120     err++;
121   }
122
123   /* only 32 slot per node */
124   if (node->mint_count < ((node->mint_level == 3) ? 1 : 2) ||
125       node->mint_count > 32) {
126     printf("incorrect mint_count\n");
127     err ++;
128   }
129
130   /* tree counts are { 1048576, 32768, 1024, 32 } */
131   if (node->mint_tree_count < ((node->mint_level == 3) ? 1 : 2)
132       || node->mint_tree_count > (unsigned) (1 << ((MINT_MAX_DEEP - node->mint_level) * MINT_BIT_SHIFT))) {
133     printf("incorrect mint_tree_count\n");
134     err ++;
135   }
136
137   if (node->mint_level == 3) {
138
139     if (node->mint_tree_count != node->mint_count) {
140       printf("tree count != mint_count\n");
141       err ++;
142     }
143
144     if (node->mint_count == 1) {
145       if (node->mint_min != node->mint_max) {
146         printf("mint_min != mint_max\n");
147         err ++;
148       }
149     } else {
150       if (node->mint_min == node->mint_max) {
151         printf("mint_min == mint_max\n");
152         err ++;
153       }
154     }
155   } 
156
157   if (node->mint_min > node->mint_max) {
158     printf("min > max\n");
159     err++;
160   }
161
162   /* check bitmaps */
163   if (node->mint_count == 32) {
164     if (node->mint_alloc_bitmap != ~0UL) {
165       printf("mint_alloc_bitmap mismatch\n");
166       err ++;
167     }
168     if (node->mint_level == 3 && node->mint_free_bitmap != 0) {
169       printf("mint_free_bitmap mismatch at level 3\n");
170       err ++;
171     }
172   }
173
174   /* build prefix from min and max values */
175   
176   offset = MINORBITS - MINT_BIT_SHIFT - node->mint_level * MINT_BIT_SHIFT;
177
178   prefix = (node->mint_min >> MINT_BIT_SHIFT);
179   prefix &= ~ ((1 << offset) - 1); 
180   if (node->mint_prefix != prefix) {
181     printf("min: bad prefix: 0x%04x (%u) (offset = %d)\n", prefix, prefix << MINT_BIT_SHIFT, offset);
182     err ++;
183   }
184
185   prefix = (node->mint_max >> MINT_BIT_SHIFT);
186   prefix &= ~ ((1 << offset) - 1); 
187   if (node->mint_prefix != prefix) {
188     printf("max: bad prefix: 0x%04x (%u) (offset = %d)\n", prefix, prefix << MINT_BIT_SHIFT, offset);
189     err ++;
190   }
191
192   /* check pointer list */
193   first = 32;
194   last = 0;
195   
196   count = 0;
197
198   for(i = 0; i < 32; i++) {
199     if (node->mint_alloc_bitmap & (1 << i)) {
200
201       count ++;
202
203       if (i < first)
204         first = i;
205           
206       if (i > last)
207         last = i;
208
209       if (node->mint_level != 3) {
210
211         if (node->mint_ptr[i] == NULL) {
212           printf("Allocated pointer %d == NULL\n", i);
213           err ++;
214         } else {
215
216           /* below is not null, check the bitmap matching */
217           if ((node->mint_free_bitmap & (1 << i))) {
218             
219             /* check there's really room below */
220             if (node->mint_ptr[i]->mint_free_bitmap == 0) {
221               printf("invalid free slot %d\n", i);
222               err ++;
223               NODE_CHECK_DUMP(node->mint_ptr[i]);
224             }
225           } else {
226
227             /* check the underlying node is really not full */
228             if (node->mint_ptr[i]->mint_free_bitmap != 0) {
229               printf("invalid non free slot %d\n", i);
230               err ++;
231               NODE_CHECK_DUMP(node->mint_ptr[i]);
232             }
233           }
234         }
235       } else {
236
237         if (node->mint_free_bitmap & (1 << i)) {
238           printf("allocated leaf pointer %d declared as free\n", i);
239           err ++;
240         }
241       }
242     } else {
243       if (node->mint_ptr[i] != NULL) {
244         printf("Unallocated pointer %d not null\n", i);
245         err ++;
246       }
247           
248       if (!(node->mint_free_bitmap & (1 << i))) {
249         printf("pointer %d not free\n", i);
250         err ++;
251       }
252           
253     }
254   }
255
256   if (count != node->mint_count) {
257     printf("No matching mint_ptr and mint_count\n");
258     err ++;
259   }
260
261   if (node->mint_level != 3) {
262
263     /* check min and max value against lower nodes values */
264
265     if (node->mint_min != node->mint_ptr[first]->mint_min) {
266       printf("Min mismatch\n");
267       err ++;
268     }
269
270     if (node->mint_max != node->mint_ptr[last]->mint_max) {
271       printf("Max mismatch\n");
272       err ++;
273     }
274   } else {
275
276     /* check min and max values against allocated id */
277     if (node->mint_min != (__u32)((node->mint_prefix << MINT_BIT_SHIFT) | first)) {
278       printf("Min mismatch\n");
279       err ++;
280     }
281     
282     if (node->mint_max != (__u32)((node->mint_prefix << MINT_BIT_SHIFT) | last)) {
283       printf("Max mismatch\n");
284       err ++;
285     }
286   }
287
288   if (err)
289     printf("Errors: %d\n", err);
290
291   return err;
292 }
293
294 int
295 node_check_dump(const char * function, int line, const char *name, 
296                 struct mint *node)
297 {
298   int ret;
299
300   ret = node_check(node);
301
302   if (ret)
303     node_dump(function, line, name, node);
304
305   return ret;
306 }
307
308 /* recursively check nodes
309  *
310  */
311 int
312 tree_check(const char * function, int line, const char *name,
313            struct mint **tree, int level)
314 {
315   int i;
316
317   struct mint * node = *tree;
318
319   if (node == NULL)
320     return 0;
321
322   if (node_check_dump(function, line, name, node))
323     return 1;
324
325   if (node->mint_level == 3)
326     return 0;
327
328   if (node->mint_level < level) {
329     printf("Error: node level lower than expected\n");
330     node_dump(function, line, name, node);
331     return 1;
332   }
333
334   for(i = 0; i < 32; i++) {
335     if (node->mint_alloc_bitmap & (1 << i)) {
336       if (tree_check(function, line, name, &node->mint_ptr[i], node->mint_level + 1))
337         return 1;
338     } 
339   }
340
341   return 0;
342 }