1/* 2 * Copyright 2008, Axel D��rfler, axeld@pinc-software.de. 3 * This file may be used under the terms of the MIT License. 4 */ 5 6 7#include <dirent.h> 8#include <unistd.h> 9#include <stdio.h> 10#include <string.h> 11 12#include <Entry.h> 13#include <File.h> 14#include <fs_attr.h> 15#include <TypeConstants.h> 16 17 18const char* kTempFile = "/tmp/bfs_attribute_iterator_test"; 19 20bool gVerbose; 21 22 23bool 24is_marker(const char* name) 25{ 26 return strstr(name, ":marker") != NULL; 27} 28 29 30int32 31attribute_index(const char* name) 32{ 33 int32 number; 34 if (sscanf(name, "test:%ld", &number) == 1) 35 return number; 36 37 return 0; 38} 39 40 41void 42add_attributes(BFile& file, int32 start, int32 count) 43{ 44 for (int32 index = start; index < start + count; index++) { 45 char name[B_ATTR_NAME_LENGTH]; 46 snprintf(name, sizeof(name), "test:%ld", index); 47 file.WriteAttr(name, B_INT32_TYPE, 0, &index, sizeof(int32)); 48 } 49} 50 51 52void 53remove_attributes(BFile& file, int32 start, int32 count) 54{ 55 for (int32 index = start; index < start + count; index++) { 56 char name[B_ATTR_NAME_LENGTH]; 57 snprintf(name, sizeof(name), "test:%ld", index); 58 file.RemoveAttr(name); 59 } 60} 61 62 63void 64add_marker_attribute(BFile& file, int32 index) 65{ 66 char name[B_ATTR_NAME_LENGTH]; 67 snprintf(name, sizeof(name), "test:%ld:marker", index); 68 file.WriteAttr(name, B_INT32_TYPE, 0, &index, sizeof(int32)); 69} 70 71 72void 73remove_marker_attribute(BFile& file, int32 index) 74{ 75 char name[B_ATTR_NAME_LENGTH]; 76 snprintf(name, sizeof(name), "test:%ld:marker", index); 77 file.RemoveAttr(name); 78} 79 80 81void 82test_remove_attributes(BFile& file, int32 start, int32 count, int32 removeAt, 83 int32 removeIndex1, int32 removeIndex2) 84{ 85 int fd = file.Dup(); 86 if (fd < 0) 87 return; 88 89 int32 index = 0; 90 bool seen[4096] = {0}; 91 92 if (gVerbose) 93 printf("test removeAt %ld\n", removeAt); 94 95 DIR* dir = fs_fopen_attr_dir(fd); 96 while (struct dirent* entry = fs_read_attr_dir(dir)) { 97 if (gVerbose) 98 printf(" %ld. %s\n", index, entry->d_name); 99 if (index == removeAt) { 100 if (removeIndex1 > 0) 101 remove_marker_attribute(file, removeIndex1); 102 if (removeIndex2 > 0) 103 remove_marker_attribute(file, removeIndex2); 104 } 105 index++; 106 107 if (is_marker(entry->d_name)) 108 continue; 109 110 int32 attributeIndex = attribute_index(entry->d_name); 111 if (attributeIndex > 0) { 112 if (seen[attributeIndex]) { 113 printf("attribute index %ld already listed!\n", attributeIndex); 114 exit(1); 115 } else 116 seen[attributeIndex] = true; 117 } 118 } 119 120 fs_close_attr_dir(dir); 121 close(fd); 122 123 for (int32 i = start; i < start + count; i++) { 124 if (!seen[i]) { 125 printf("attribute index %ld not listed, saw only %ld/%ld!\n", i, 126 index, count); 127 exit(1); 128 } 129 } 130} 131 132 133void 134test_add_attributes(BFile& file, int32 start, int32 count, int32 addAt, 135 int32 addIndex1, int32 addIndex2) 136{ 137 int fd = file.Dup(); 138 if (fd < 0) 139 return; 140 141 int32 index = 0; 142 bool seen[4096] = {0}; 143 144 if (gVerbose) 145 printf("test addAt %ld\n", addAt); 146 147 DIR* dir = fs_fopen_attr_dir(fd); 148 while (struct dirent* entry = fs_read_attr_dir(dir)) { 149 if (gVerbose) 150 printf(" %ld. %s\n", index, entry->d_name); 151 if (index == addAt) { 152 if (addIndex1 > 0) 153 add_marker_attribute(file, addIndex1); 154 if (addIndex2 > 0) 155 add_marker_attribute(file, addIndex2); 156 } 157 index++; 158 159 if (is_marker(entry->d_name)) 160 continue; 161 162 int32 attributeIndex = attribute_index(entry->d_name); 163 if (attributeIndex > 0) { 164 if (seen[attributeIndex]) { 165 printf("attribute index %ld already listed!\n", attributeIndex); 166 exit(1); 167 } else 168 seen[attributeIndex] = true; 169 } 170 } 171 172 fs_close_attr_dir(dir); 173 close(fd); 174 175 for (int32 i = start; i < start + count; i++) { 176 if (!seen[i]) { 177 printf("attribute index %ld not listed, saw only %ld/%ld!\n", i, 178 index, count); 179 exit(1); 180 } 181 } 182} 183 184 185int 186main(int argc, char** argv) 187{ 188 if (argc > 1 && !strcmp(argv[1], "-v")) 189 gVerbose = true; 190 191 BFile file; 192 status_t status = file.SetTo(kTempFile, B_CREATE_FILE | B_READ_WRITE); 193 if (status != B_OK) { 194 fprintf(stderr, "Could not create temporary file: %s\n", 195 strerror(status)); 196 return 1; 197 } 198 199 puts("--------- Remove Tests ----------"); 200 201 // remove test, many attributes 202 203 puts("Test 1..."); 204 205 for (int32 count = 5; count <= 100; count += 5) { 206 add_attributes(file, 1, count); 207 add_marker_attribute(file, count); 208 add_attributes(file, count + 1, count); 209 210 test_remove_attributes(file, 1, count, 211 count & 1 ? count - 1 : count + 1, count, -1); 212 213 remove_attributes(file, 1, count * 2); 214 } 215 216 // remove test, all positions 217 218 puts("Test 2..."); 219 220 for (int32 i = 1; i < 100; i++) { 221 add_attributes(file, 1, 50); 222 add_marker_attribute(file, 51); 223 add_attributes(file, 51, 50); 224 225 test_remove_attributes(file, 1, 100, i, 51, -1); 226 227 remove_attributes(file, 1, 100); 228 } 229 230 // remove test, all positions, remove many 231 232 puts("Test 3..."); 233 234 for (int32 i = 1; i < 100; i++) { 235 add_attributes(file, 1, 33); 236 add_marker_attribute(file, 33); 237 add_attributes(file, 34, 34); 238 add_marker_attribute(file, 67); 239 add_attributes(file, 68, 33); 240 241 test_remove_attributes(file, 1, 100, i, 33, 67); 242 243 remove_attributes(file, 1, 100); 244 } 245 246 puts("--------- Add Tests ----------"); 247 248 // add test, many attributes 249 250 puts("Test 4..."); 251 252 for (int32 count = 10; count <= 200; count += 10) { 253 add_attributes(file, 1, count); 254 255 int32 half = count / 2; 256 257 test_add_attributes(file, 1, count, 258 half & 1 ? half - 1 : half + 1, half - 2, half + 2); 259 260 remove_attributes(file, 1, count); 261 } 262 263 // add test, all iterator positions 264 265 puts("Test 5..."); 266 267 for (int32 i = 1; i < 100; i++) { 268 add_attributes(file, 1, 100); 269 270 test_add_attributes(file, 1, 100, i, 50, -1); 271 272 remove_attributes(file, 1, 100); 273 } 274 275 // add test, all attribute positions 276 277 puts("Test 6..."); 278 279 for (int32 i = 1; i < 100; i++) { 280 add_attributes(file, 1, 100); 281 282 test_add_attributes(file, 1, 100, 50, i, -1); 283 284 remove_attributes(file, 1, 100); 285 } 286 287 // add test, many attributes 288 289 puts("Test 7..."); 290 291 for (int32 i = 1; i < 100; i++) { 292 add_attributes(file, 1, 100); 293 294 test_add_attributes(file, 1, 100, i, 33, 67); 295 296 remove_attributes(file, 1, 100); 297 } 298 299 // add test, many attributes 300 301 puts("Test 8..."); 302 303 for (int32 i = 1; i < 100; i++) { 304 add_attributes(file, 1, 100); 305 306 test_add_attributes(file, 1, 100, 50, i - 1, i + 1); 307 308 remove_attributes(file, 1, 100); 309 } 310 311 BEntry entry; 312 if (entry.SetTo(kTempFile) == B_OK) 313 entry.Remove(); 314 315 return 0; 316} 317