{"id":13755800,"url":"https://github.com/BenjaminKim/FileSystemTest","last_synced_at":"2025-05-10T02:33:05.832Z","repository":{"id":10552939,"uuid":"12752490","full_name":"BenjaminKim/FileSystemTest","owner":"BenjaminKim","description":"FileSystem Api Test For Windows","archived":false,"fork":false,"pushed_at":"2024-08-19T02:44:38.000Z","size":83828,"stargazers_count":18,"open_issues_count":0,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-16T10:32:14.658Z","etag":null,"topics":["filesystem","filesystem-library"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BenjaminKim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-11T09:25:17.000Z","updated_at":"2024-08-19T02:44:41.000Z","dependencies_parsed_at":"2024-11-16T10:31:36.755Z","dependency_job_id":"01df9e10-015a-46ac-aafe-5bf60fd5afe3","html_url":"https://github.com/BenjaminKim/FileSystemTest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjaminKim%2FFileSystemTest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjaminKim%2FFileSystemTest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjaminKim%2FFileSystemTest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjaminKim%2FFileSystemTest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BenjaminKim","download_url":"https://codeload.github.com/BenjaminKim/FileSystemTest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253354489,"owners_count":21895436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filesystem","filesystem-library"],"created_at":"2024-08-03T11:00:30.104Z","updated_at":"2025-05-10T02:33:04.815Z","avatar_url":"https://github.com/BenjaminKim.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# FileSystemTest\n\nWant to create your own file system? And it has to be compatible with Windows?  \nThat's what `FileSystemTest` is designed for.\n\nCreating a filesystem that is fully compatible with Windows is incredibly difficult.  \n`FileSystemTest` will help you a lot.\n\n## How does it work?\n\nIf you're creating a network file system, what do you need to do to make it compatible with the Windows APIs?\n\nWindows has several File APIs\n* CreateFile\n* ReadFile\n* WriteFile\n* CloseFile\n* MoveFile\nand so on.\n\nImagine what would happen if you double-clicked the `docx` file inside your filesystem volume in Windows Explorer.  \nIf you have Word installed, it will probably open Word.  \nWord would **open** your file, **read** it, **change the time**, **create a temporary file**, and a whole bunch of other things.  \nYou just double-clicked it to open the document.\n\nMatching the results of these APIs with the results of NTFS is what makes it compatible.  \nSo what should we expect to see when we put something in?\n\nFor example, something like this.\n* What happens if you call `RemoveDirectory` on a directory that has files in it? Should it delete the directory and all the files it contains and return success? Your filesystem might do that, but that's incompatible with NTFS, because NTFS requires you to return `ERROR_DIR_NOT_EMPTY`, which is `STATUS_DIRECTORY_NOT_EMPTY` at the kernel level.\n* Calling `DeleteFile` while a file is open should return `STATUS_ACCESS_DENIED`.\n\nThese are the rules of NTFS.  \nYou should be familiar with these rules so that you can make your file system NTFS-compatible.  \nIf you don't know these rules, that's okay, because `FileSystemTest` has a test case for that.\n\n## How can I use it?\n`FileSystemTest` has a lot of test cases.  \nIt calls almost all of the File APIs with different inputs and outputs the results.\n\nYou can use it to \n1. Run the tests on an NTFS(or SMB) file system and save the output file.\n2. Run the tests on your own file system and save the output file.\n3. Compare the output files in 1 and 2 with your favorite diff tool. (I use `WinMerge`)\n4. If there is something difference, fix your filesystem to match the output in NTFS(or SMB) (the correct answer).\n\nWhen all things are equal, you can say that we have created a file system that is fully compatible with NTFS(or SMB).  \n(But it's never easy to make everything equal).\n\nFilesystems are very complex. If you write one line of code wrong, you'll see your test cases break like crazy.  \nThat's why `FileSystemTest` is so nice. Imagine how hard it would be if you tried to test this manually.\n\nNote that `FileSystemTest` doesn't have all the test cases.  \nPlease add any tests that are missing!\n\n## NTFS compatible vs SMB compatible?\nIf you're creating a network file system, you should follow SMB, not NTFS.  \nNTFS and SMB have subtle differences in input and output. SMB is the way to go.  \nSMB is standard Windows network filesystem.\n\n### Execution\n\n```FileSystemTest.exe [base_directory] [option]```\n\n`base_directory` is a required value. Specify which directory on which volume.  \nFor example, you could specify `C:\\my_test`, which is probably an NTFS directory.  \nAnd you could specify `X:\\my_test`, if you mount Windows network filesystem(SMB) to `X` volume.  \nIf you mounted your file system to drive `Z`, you might say `Z:\\my_test`.\n\n```\n#  -v [ --version ]          print the version number\n#  -d [ --duration ]         print the api duration\n#  -t [ --time ]             print the output with time as prefix of lines\n#  -c [ --case ] arg         Run only the specified case.\n#  -s [ --statistics ]       print api statistics\n#  -f [ --full-log ]         print everything include utility functors.\n#  -i [ --io-test ]          The program will run only for testing io performance.\n#  -r [ --createfile-test ]  The program will run only for testing createfile.\n#  -l [ --filelist-test ]    The program will run only for testing filelist.\n#  -o [ --openfile-test ]    The program will run only for testing open files.\n#  --starttime arg           The program will run on specified time.\n#  --endtime arg             The program will run on specified time.\n#  -q [ --quiet ]            print only test number and result in stdout (stderrstill have some detail) to compare results on 2 file system\n\n```\n\n## Basic Example\n\n```bash\n# `C:\\my_test` is a filesystem base directory you want to test.\n# It can be a NTFS volume, or Windows network(SMB) or your own filesystem.\n# In this example, it points a `NTFS` volume(C:)\nC:\\YourPath\u003e FileSystemTest.exe C:\\my_test -t -d -s -f\n```\n\n## Result\nThe above command tries all APIs on the `C:\\my_test` (NTFS volume in this case) using all combinations of parameters and prints the results.  \nThe result of the API can be either success or failure. (API fails doesn't mean the test failed)  \nYou should also run this test on *your own filesystem* and compare it with NTFS's result using any `diff` tool you prefer.  \nIf the result is different, your file system is not NTFS compliant and applications will not work properly.  \n\nIf your file system is a network file system, it is better to compare it to the SMB(Windows Network Drive) rather than to NTFS.\n\n```\nCurrent directory path has been set as C:\\test_base_directory\n0x00002020[FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED]\nThe configuration was set to print duration.\nThe configuration was set to print time.\nThe configuration was set to print api statistics.\n(Case1)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.731] CreateFile IN\n[23:40:49.731]              lpFileName = Case1test\n[23:40:49.731]         dwDesiredAccess = 0x80000000[GENERIC_READ]\n[23:40:49.732]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.732]    lpSecurityAttributes = (NULL)\n[23:40:49.732]   dwCreationDisposition = 2(CREATE_ALWAYS)\n[23:40:49.732]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.732]           hTemplateFile = (NULL)\n[23:40:49.732] CreateFile OUT\n[23:40:49.732] return: (VALID_HANDLE)\n[23:40:49.732] last error: 0(ERROR_SUCCESS)\n[23:40:49.732] Duration: 0.000285661 second.\n(MESSAGE) Deletion success.\n(Case1)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Success\n\n(Case2)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.734] CreateFile IN\n[23:40:49.734]              lpFileName = Case2test\n[23:40:49.734]         dwDesiredAccess = 0x80000000[GENERIC_READ]\n[23:40:49.734]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.734]    lpSecurityAttributes = (NULL)\n[23:40:49.734]   dwCreationDisposition = 1(CREATE_NEW)\n[23:40:49.734]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.734]           hTemplateFile = (NULL)\n[23:40:49.734] CreateFile OUT\n[23:40:49.734] return: (VALID_HANDLE)\n[23:40:49.735] last error: 0(ERROR_SUCCESS)\n[23:40:49.735] Duration: 0.00018816 second.\n(MESSAGE) Deletion success.\n(Case2)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Success\n\n(Case3)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.736] CreateFile IN\n[23:40:49.736]              lpFileName = Case3test\n[23:40:49.736]         dwDesiredAccess = 0x80000000[GENERIC_READ]\n[23:40:49.736]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.736]    lpSecurityAttributes = (NULL)\n[23:40:49.736]   dwCreationDisposition = 4(OPEN_ALWAYS)\n[23:40:49.736]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.736]           hTemplateFile = (NULL)\n[23:40:49.736] CreateFile OUT\n[23:40:49.737] return: (VALID_HANDLE)\n[23:40:49.737] last error: 0(ERROR_SUCCESS)\n[23:40:49.737] Duration: 0.000183456 second.\n(MESSAGE) Deletion success.\n(Case3)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Success\n\n(Case4)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.738] CreateFile IN\n[23:40:49.738]              lpFileName = Case4test\n[23:40:49.738]         dwDesiredAccess = 0x80000000[GENERIC_READ]\n[23:40:49.738]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.738]    lpSecurityAttributes = (NULL)\n[23:40:49.738]   dwCreationDisposition = 3(OPEN_EXISTING)\n[23:40:49.738]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.738]           hTemplateFile = (NULL)\n[23:40:49.738] CreateFile OUT\n[23:40:49.738] return: (INVALID_HANDLE)\n[23:40:49.739] last error: 2(ERROR_FILE_NOT_FOUND)\n[23:40:49.739] Duration: 7.22704e-005 second.\n(ERROR) CreateFile\n(MESSAGE) Deletion success(file not found).\n(ERROR) Sub_CreateFile_Disposition\n(Case4)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Fail\n\n(Case5)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.739] CreateFile IN\n[23:40:49.739]              lpFileName = Case5test\n[23:40:49.740]         dwDesiredAccess = 0x80000000[GENERIC_READ]\n[23:40:49.740]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.740]    lpSecurityAttributes = (NULL)\n[23:40:49.740]   dwCreationDisposition = 5(TRUNCATE_EXISTING)\n[23:40:49.740]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.740]           hTemplateFile = (NULL)\n[23:40:49.740] CreateFile OUT\n[23:40:49.740] return: (INVALID_HANDLE)\n[23:40:49.740] last error: 87(ERROR_INVALID_PARAMETER)\n[23:40:49.740] Duration: 3.97701e-005 second.\n(ERROR) CreateFile\n(MESSAGE) Deletion success(file not found).\n(ERROR) Sub_CreateFile_Disposition\n(Case5)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Fail\n\n(Case6)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: Start.\n[23:40:49.741] CreateFile IN\n[23:40:49.741]              lpFileName = Case6test\n[23:40:49.741]         dwDesiredAccess = 0x40000000[GENERIC_WRITE]\n[23:40:49.742]             dwShareMode = 0x00000007[FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE]\n[23:40:49.742]    lpSecurityAttributes = (NULL)\n[23:40:49.742]   dwCreationDisposition = 2(CREATE_ALWAYS)\n[23:40:49.742]    dwFlagsAndAttributes = 0x00000000\n[23:40:49.742]           hTemplateFile = (NULL)\n[23:40:49.742] CreateFile OUT\n[23:40:49.742] return: (VALID_HANDLE)\n[23:40:49.742] last error: 0(ERROR_SUCCESS)\n[23:40:49.742] Duration: 0.000193719 second.\n(MESSAGE) Deletion success.\n(Case6)[Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]: End. Success\n\n# ...and hundred of test cases are omitted here.\n\n# And it gives you a statistic for tested functions.\n# You could measure how your file system fast.\n\nFunction Name : CreateDirectory\nMin : 0.000292930330\nMax : 0.000369049452\nSum : 0.000661979781\nCount : 2\nOperation per sec : 3,021.240310077520\nAvg : 0.000330989891\nStdDev : 0.000038059561\n\nFunction Name : CreateDirectoryEx\nMin : 0.000197139974\nMax : 0.000587143566\nSum : 0.063823745745\nCount : 255\nOperation per sec : 3,995.378162521441\nAvg : 0.000250289199\nStdDev : 0.000052711293\n\nFunction Name : RemoveDirectory\nMin : 0.000094079814\nMax : 0.000222370469\nSum : 0.000442602761\nCount : 3\nOperation per sec : 6,778.086956521739\nAvg : 0.000147534254\nStdDev : 0.000054513046\n\nFunction Name : CopyFile\nMin : 0.000091941636\nMax : 0.009981868254\nSum : 0.083748995057\nCount : 20\nOperation per sec : 238.808835694080\nAvg : 0.004187449753\nStdDev : 0.004236031032\n\nFunction Name : CopyFileEx\nMin : 0.000085954739\nMax : 0.009361796753\nSum : 0.063747626623\nCount : 21\nOperation per sec : 329.424028979674\nAvg : 0.003035601268\nStdDev : 0.004084865451\n\nFunction Name : CreateFile\nMin : 0.000022664682\nMax : 0.000303621218\nSum : 0.008617710953\nCount : 75\nOperation per sec : 8,703.007145692734\nAvg : 0.000114902813\nStdDev : 0.000077592803\n\nFunction Name : DeleteFile\nMin : 0.000060724244\nMax : 0.000205265048\nSum : 0.000695335352\nCount : 7\nOperation per sec : 10,067.084870848710\nAvg : 0.000099333622\nStdDev : 0.000048242309\n\nFunction Name : GetFileAttributes\nMin : 0.000061151879\nMax : 0.000516583705\nSum : 0.009245907528\nCount : 116\nOperation per sec : 12,546.091300124879\nAvg : 0.000079706099\nStdDev : 0.000041475734\n\nFunction Name : GetFileInformationByHandleEx\nMin : 0.000035921383\nMax : 0.000131711739\nSum : 0.001761430697\nCount : 25\nOperation per sec : 14,193.008011653314\nAvg : 0.000070457228\nStdDev : 0.000022356883\n\nFunction Name : GetFileSize\nMin : 0.000035493748\nMax : 0.000035493748\nSum : 0.000035493748\nCount : 1\nOperation per sec : 28,173.975903614457\nAvg : 0.000035493748\nStdDev : 0.000000000000\n\nFunction Name : GetFileSizeEx\nMin : 0.000035493748\nMax : 0.000035493748\nSum : 0.000035493748\nCount : 1\nOperation per sec : 28,173.975903614457\nAvg : 0.000035493748\nStdDev : 0.000000000000\n\nFunction Name : GetFileType\nMin : 0.000029079215\nMax : 0.000029079215\nSum : 0.000029079215\nCount : 1\nOperation per sec : 34,388.823529411762\nAvg : 0.000029079215\nStdDev : 0.000000000000\n\nFunction Name : SetFileAttributes\nMin : 0.000086810010\nMax : 0.000507175724\nSum : 0.016205247943\nCount : 75\nOperation per sec : 4,628.130360205832\nAvg : 0.000216069973\nStdDev : 0.000067332896\n\nFunction Name : MoveFile\nMin : 0.000061151879\nMax : 0.006358940148\nSum : 0.012365508630\nCount : 30\nOperation per sec : 2,426.103195462720\nAvg : 0.000412183621\nStdDev : 0.001110592118\n\nFunction Name : MoveFileEx\nMin : 0.000048750449\nMax : 0.008298267221\nSum : 0.053534407554\nCount : 152\nOperation per sec : 2,839.295454000816\nAvg : 0.000352200050\nStdDev : 0.000747844944\n\nFunction Name : SetFileInformationByHandle\nMin : 0.000025658131\nMax : 0.000765895212\nSum : 0.007700432767\nCount : 30\nOperation per sec : 3,895.884933636919\nAvg : 0.000256681092\nStdDev : 0.000166413330\n\nFunction Name : CreateDirectory\nMin : 0.000157797506\nMax : 0.000715861857\nSum : 0.067548451104\nCount : 302\nOperation per sec : 4,470.864913458009\nAvg : 0.000223670368\nStdDev : 0.000069670169\n\nFunction Name : RemoveDirectory\nMin : 0.000051316262\nMax : 0.000988693317\nSum : 0.088256273413\nCount : 564\nOperation per sec : 6,390.480565165561\nAvg : 0.000156482754\nStdDev : 0.000052658218\n\nFunction Name : ReadFile\nMin : 0.000059868972\nMax : 0.000415661723\nSum : 0.004417474898\nCount : 63\nOperation per sec : 14,261.541142303968\nAvg : 0.000070118649\nStdDev : 0.000044347422\n\nFunction Name : WriteFile\nMin : 0.000049178085\nMax : 0.001336360993\nSum : 0.063155351431\nCount : 522\nOperation per sec : 8,265.332836780995\nAvg : 0.000120987263\nStdDev : 0.000093946882\n\nFunction Name : CreateFile\nMin : 0.000058586066\nMax : 0.008014744873\nSum : 0.150909153111\nCount : 716\nOperation per sec : 4,744.576357639166\nAvg : 0.000210766974\nStdDev : 0.000325589034\n\nFunction Name : DeleteFile\nMin : 0.000066283505\nMax : 0.000561485435\nSum : 0.015803698192\nCount : 60\nOperation per sec : 3,796.579716419526\nAvg : 0.000263394970\nStdDev : 0.000088725795\n\nFunction Name : SetFileAttributes\nMin : 0.000059868972\nMax : 0.000371187629\nSum : 0.139102991738\nCount : 843\nOperation per sec : 6,060.257866971633\nAvg : 0.000165009480\nStdDev : 0.000048513022\n\nFunction Name : CloseHandle\nMin : 0.000039342468\nMax : 0.015926857221\nSum : 1.799948683738\nCount : 714\nOperation per sec : 396.677975572763\nAvg : 0.002520936532\nStdDev : 0.003741849575\n```\n\n\n#### Example integrated in a tests suite\n\u003e \nC:\\YourPath\u003e FileSystemTest.exe C:\\test_base_directory -q\n\n```\nCurrent directory path has been set as C:\\test_base_directory\n0x00002020[FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED]\n(Case 00001) OK [Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]\n(Case 00002) OK [Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]\n(Case 00003) OK [Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]\n(Case 00004) KO [Calling CreateFile with dwDesiredAccess, dwCreateDisposition.]\n...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBenjaminKim%2FFileSystemTest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBenjaminKim%2FFileSystemTest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBenjaminKim%2FFileSystemTest/lists"}