1/* 2 Unix SMB/CIFS implementation. 3 4 local testing of idtree routines. 5 6 Copyright (C) Andrew Tridgell 2004 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "torture/torture.h" 24 25static bool torture_local_idtree_simple(struct torture_context *tctx) 26{ 27 struct idr_context *idr; 28 int i, ret; 29 int *ids; 30 int *present; 31 extern int torture_numops; 32 int n = torture_numops; 33 TALLOC_CTX *mem_ctx = tctx; 34 35 idr = idr_init(mem_ctx); 36 37 ids = talloc_zero_array(mem_ctx, int, n); 38 present = talloc_zero_array(mem_ctx, int, n); 39 40 for (i=0;i<n;i++) { 41 ids[i] = -1; 42 } 43 44 for (i=0;i<n;i++) { 45 int ii = random() % n; 46 void *p = idr_find(idr, ids[ii]); 47 if (present[ii]) { 48 if (p != &ids[ii]) { 49 torture_fail(tctx, talloc_asprintf(tctx, 50 "wrong ptr at %d - %p should be %p", 51 ii, p, &ids[ii])); 52 } 53 if (random() % 7 == 0) { 54 if (idr_remove(idr, ids[ii]) != 0) { 55 torture_fail(tctx, talloc_asprintf(tctx, 56 "remove failed at %d (id=%d)", 57 i, ids[ii])); 58 } 59 present[ii] = 0; 60 ids[ii] = -1; 61 } 62 } else { 63 if (p != NULL) { 64 torture_fail(tctx, 65 talloc_asprintf(tctx, 66 "non-present at %d gave %p (would be %d)", 67 ii, p, 68 (int)((((char *)p) - (char *)(&ids[0])) / sizeof(int)))); 69 } 70 if (random() % 5) { 71 ids[ii] = idr_get_new(idr, &ids[ii], n); 72 if (ids[ii] < 0) { 73 torture_fail(tctx, talloc_asprintf(tctx, 74 "alloc failure at %d (ret=%d)", 75 ii, ids[ii])); 76 } else { 77 present[ii] = 1; 78 } 79 } 80 } 81 } 82 83 torture_comment(tctx, "done %d random ops\n", i); 84 85 for (i=0;i<n;i++) { 86 if (present[i]) { 87 if (idr_remove(idr, ids[i]) != 0) { 88 torture_fail(tctx, talloc_asprintf(tctx, 89 "delete failed on cleanup at %d (id=%d)", 90 i, ids[i])); 91 } 92 } 93 } 94 95 /* now test some limits */ 96 for (i=0;i<25000;i++) { 97 ret = idr_get_new_above(idr, &ids[0], random() % 25000, 0x10000-3); 98 torture_assert(tctx, ret != -1, "idr_get_new_above failed"); 99 } 100 101 ret = idr_get_new_above(idr, &ids[0], 0x10000-2, 0x10000); 102 torture_assert_int_equal(tctx, ret, 0x10000-2, "idr_get_new_above failed"); 103 ret = idr_get_new_above(idr, &ids[0], 0x10000-1, 0x10000); 104 torture_assert_int_equal(tctx, ret, 0x10000-1, "idr_get_new_above failed"); 105 ret = idr_get_new_above(idr, &ids[0], 0x10000, 0x10000); 106 torture_assert_int_equal(tctx, ret, 0x10000, "idr_get_new_above failed"); 107 ret = idr_get_new_above(idr, &ids[0], 0x10000+1, 0x10000); 108 torture_assert_int_equal(tctx, ret, -1, "idr_get_new_above succeeded above limit"); 109 ret = idr_get_new_above(idr, &ids[0], 0x10000+2, 0x10000); 110 torture_assert_int_equal(tctx, ret, -1, "idr_get_new_above succeeded above limit"); 111 112 torture_comment(tctx, "cleaned up\n"); 113 return true; 114} 115 116struct torture_suite *torture_local_idtree(TALLOC_CTX *mem_ctx) 117{ 118 struct torture_suite *suite = torture_suite_create(mem_ctx, "IDTREE"); 119 torture_suite_add_simple_test(suite, "idtree", torture_local_idtree_simple); 120 return suite; 121} 122