diff --git a/src/tests/add-ons/kernel/file_systems/bfs/Jamfile b/src/tests/add-ons/kernel/file_systems/bfs/Jamfile index fe4d543076..537bb4bce6 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/Jamfile +++ b/src/tests/add-ons/kernel/file_systems/bfs/Jamfile @@ -1,5 +1,9 @@ SubDir HAIKU_TOP src tests add-ons kernel file_systems bfs ; +SimpleTest bfs_attribute_iterator_test : + bfs_attribute_iterator_test.cpp + : be ; + SubInclude HAIKU_TOP src tests add-ons kernel file_systems bfs array ; SubInclude HAIKU_TOP src tests add-ons kernel file_systems bfs bufferPool ; SubInclude HAIKU_TOP src tests add-ons kernel file_systems bfs bfs_shell ; diff --git a/src/tests/add-ons/kernel/file_systems/bfs/bfs_attribute_iterator_test.cpp b/src/tests/add-ons/kernel/file_systems/bfs/bfs_attribute_iterator_test.cpp new file mode 100644 index 0000000000..e66746b238 --- /dev/null +++ b/src/tests/add-ons/kernel/file_systems/bfs/bfs_attribute_iterator_test.cpp @@ -0,0 +1,316 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. + * This file may be used under the terms of the MIT License. + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + + +const char* kTempFile = "/tmp/bfs_attribute_iterator_test"; + +bool gVerbose; + + +bool +is_marker(const char* name) +{ + return strstr(name, ":marker") != NULL; +} + + +int32 +attribute_index(const char* name) +{ + int32 number; + if (sscanf(name, "test:%ld", &number) == 1) + return number; + + return 0; +} + + +void +add_attributes(BFile& file, int32 start, int32 count) +{ + for (int32 index = start; index < start + count; index++) { + char name[B_ATTR_NAME_LENGTH]; + snprintf(name, sizeof(name), "test:%ld", index); + file.WriteAttr(name, B_INT32_TYPE, 0, &index, sizeof(int32)); + } +} + + +void +remove_attributes(BFile& file, int32 start, int32 count) +{ + for (int32 index = start; index < start + count; index++) { + char name[B_ATTR_NAME_LENGTH]; + snprintf(name, sizeof(name), "test:%ld", index); + file.RemoveAttr(name); + } +} + + +void +add_marker_attribute(BFile& file, int32 index) +{ + char name[B_ATTR_NAME_LENGTH]; + snprintf(name, sizeof(name), "test:%ld:marker", index); + file.WriteAttr(name, B_INT32_TYPE, 0, &index, sizeof(int32)); +} + + +void +remove_marker_attribute(BFile& file, int32 index) +{ + char name[B_ATTR_NAME_LENGTH]; + snprintf(name, sizeof(name), "test:%ld:marker", index); + file.RemoveAttr(name); +} + + +void +test_remove_attributes(BFile& file, int32 start, int32 count, int32 removeAt, + int32 removeIndex1, int32 removeIndex2) +{ + int fd = file.Dup(); + if (fd < 0) + return; + + int32 index = 0; + bool seen[4096] = {0}; + + if (gVerbose) + printf("test removeAt %ld\n", removeAt); + + DIR* dir = fs_fopen_attr_dir(fd); + while (struct dirent* entry = fs_read_attr_dir(dir)) { + if (gVerbose) + printf(" %ld. %s\n", index, entry->d_name); + if (index == removeAt) { + if (removeIndex1 > 0) + remove_marker_attribute(file, removeIndex1); + if (removeIndex2 > 0) + remove_marker_attribute(file, removeIndex2); + } + index++; + + if (is_marker(entry->d_name)) + continue; + + int32 attributeIndex = attribute_index(entry->d_name); + if (attributeIndex > 0) { + if (seen[attributeIndex]) { + printf("attribute index %ld already listed!\n", attributeIndex); + exit(1); + } else + seen[attributeIndex] = true; + } + } + + fs_close_attr_dir(dir); + close(fd); + + for (int32 i = start; i < start + count; i++) { + if (!seen[i]) { + printf("attribute index %ld not listed, saw only %ld/%ld!\n", i, + index, count); + exit(1); + } + } +} + + +void +test_add_attributes(BFile& file, int32 start, int32 count, int32 addAt, + int32 addIndex1, int32 addIndex2) +{ + int fd = file.Dup(); + if (fd < 0) + return; + + int32 index = 0; + bool seen[4096] = {0}; + + if (gVerbose) + printf("test addAt %ld\n", addAt); + + DIR* dir = fs_fopen_attr_dir(fd); + while (struct dirent* entry = fs_read_attr_dir(dir)) { + if (gVerbose) + printf(" %ld. %s\n", index, entry->d_name); + if (index == addAt) { + if (addIndex1 > 0) + add_marker_attribute(file, addIndex1); + if (addIndex2 > 0) + add_marker_attribute(file, addIndex2); + } + index++; + + if (is_marker(entry->d_name)) + continue; + + int32 attributeIndex = attribute_index(entry->d_name); + if (attributeIndex > 0) { + if (seen[attributeIndex]) { + printf("attribute index %ld already listed!\n", attributeIndex); + exit(1); + } else + seen[attributeIndex] = true; + } + } + + fs_close_attr_dir(dir); + close(fd); + + for (int32 i = start; i < start + count; i++) { + if (!seen[i]) { + printf("attribute index %ld not listed, saw only %ld/%ld!\n", i, + index, count); + exit(1); + } + } +} + + +int +main(int argc, char** argv) +{ + if (argc > 1 && !strcmp(argv[1], "-v")) + gVerbose = true; + + BFile file; + status_t status = file.SetTo(kTempFile, B_CREATE_FILE | B_READ_WRITE); + if (status != B_OK) { + fprintf(stderr, "Could not create temporary file: %s\n", + strerror(status)); + return 1; + } + + puts("--------- Remove Tests ----------"); + + // remove test, many attributes + + puts("Test 1..."); + + for (int32 count = 5; count <= 100; count += 5) { + add_attributes(file, 1, count); + add_marker_attribute(file, count); + add_attributes(file, count + 1, count); + + test_remove_attributes(file, 1, count, + count & 1 ? count - 1 : count + 1, count, -1); + + remove_attributes(file, 1, count * 2); + } + + // remove test, all positions + + puts("Test 2..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 50); + add_marker_attribute(file, 51); + add_attributes(file, 51, 50); + + test_remove_attributes(file, 1, 100, i, 51, -1); + + remove_attributes(file, 1, 100); + } + + // remove test, all positions, remove many + + puts("Test 3..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 33); + add_marker_attribute(file, 33); + add_attributes(file, 34, 34); + add_marker_attribute(file, 67); + add_attributes(file, 68, 33); + + test_remove_attributes(file, 1, 100, i, 33, 67); + + remove_attributes(file, 1, 100); + } + + puts("--------- Add Tests ----------"); + + // add test, many attributes + + puts("Test 4..."); + + for (int32 count = 10; count <= 200; count += 10) { + add_attributes(file, 1, count); + + int32 half = count / 2; + + test_add_attributes(file, 1, count, + half & 1 ? half - 1 : half + 1, half - 2, half + 2); + + remove_attributes(file, 1, count); + } + + // add test, all iterator positions + + puts("Test 5..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 100); + + test_add_attributes(file, 1, 100, i, 50, -1); + + remove_attributes(file, 1, 100); + } + + // add test, all attribute positions + + puts("Test 6..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 100); + + test_add_attributes(file, 1, 100, 50, i, -1); + + remove_attributes(file, 1, 100); + } + + // add test, many attributes + + puts("Test 7..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 100); + + test_add_attributes(file, 1, 100, i, 33, 67); + + remove_attributes(file, 1, 100); + } + + // add test, many attributes + + puts("Test 8..."); + + for (int32 i = 1; i < 100; i++) { + add_attributes(file, 1, 100); + + test_add_attributes(file, 1, 100, 50, i - 1, i + 1); + + remove_attributes(file, 1, 100); + } + + BEntry entry; + if (entry.SetTo(kTempFile) == B_OK) + entry.Remove(); + + return 0; +}