diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-09-29 10:07:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-29 10:07:37 -0400 |
| commit | 70a6fbb33136e8e25a21977b4b07d3ced7597354 (patch) | |
| tree | 1d117b94181c3017bfd5e9466071f04f4deb3ead /tools | |
| parent | c2c913f3a0e1e6c411e0abf51a1ed58551a955a4 (diff) | |
RIFF filesystem improvements (#2418)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Remove ref count for Entry in RiffFileSystem.
Free up backing Entry types (to work around Dictionary not doing this).
* Some small improvements to RiffFileSystem.
* Add testing for file systems.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/slang-unit-test/unit-test-file-system.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/tools/slang-unit-test/unit-test-file-system.cpp b/tools/slang-unit-test/unit-test-file-system.cpp new file mode 100644 index 000000000..f1fd2c6bc --- /dev/null +++ b/tools/slang-unit-test/unit-test-file-system.cpp @@ -0,0 +1,197 @@ +// unit-test-file-system.cpp + +#include "../../source/core/slang-file-system.h" +#include "../../source/core/slang-riff-file-system.h" +#include "../../source/core/slang-zip-file-system.h" + +#include "../../source/core/slang-deflate-compression-system.h" +#include "../../source/core/slang-lz4-compression-system.h" + +#include "tools/unit-test/slang-unit-test.h" + +using namespace Slang; + +namespace { + +enum class FileSystemType +{ + Zip, + RiffUncompressed, + RiffDeflate, + RiffLZ4, + Relative, + CountOf, +}; + +struct Entry +{ + typedef Entry ThisType; + + bool operator<(const ThisType& rhs) const { return name < rhs.name; } + bool operator==(const ThisType& rhs) const { return name == rhs.name && type == rhs.type; } + bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + + SlangPathType type; + String name; +}; + +} // + +static SlangResult _createAndCheckFile(ISlangMutableFileSystem* fileSystem, const char* path, const char* contents) +{ + UnownedStringSlice contentsSlice(contents); + + SLANG_RETURN_ON_FAIL(fileSystem->saveFile(path, contentsSlice.begin(), contentsSlice.getLength())); + + SlangPathType pathType; + SLANG_RETURN_ON_FAIL(fileSystem->getPathType(path, &pathType)); + + if (pathType != SLANG_PATH_TYPE_FILE) + { + return SLANG_FAIL; + } + + ComPtr<ISlangBlob> blob; + SLANG_RETURN_ON_FAIL(fileSystem->loadFile(path, blob.writeRef())); + + if (blob->getBufferSize() != contentsSlice.getLength()) + { + return SLANG_FAIL; + } + if (contentsSlice != UnownedStringSlice((const char*)blob->getBufferPointer(), blob->getBufferSize())) + { + return SLANG_FAIL; + } + + return SLANG_OK; +} + +static SlangResult _createAndCheckDirectory(ISlangMutableFileSystem* fileSystem, const char* path) +{ + SLANG_RETURN_ON_FAIL(fileSystem->createDirectory(path)); + + SlangPathType pathType; + SLANG_RETURN_ON_FAIL(fileSystem->getPathType(path, &pathType)); + + if (pathType != SLANG_PATH_TYPE_DIRECTORY) + { + return SLANG_FAIL; + } + + return SLANG_OK; +} + +static void _entryCallback(SlangPathType pathType, const char* name, void* userData) +{ + List<Entry>& out = *(List<Entry>*)userData; + out.add(Entry{pathType, name}); +} + +static SlangResult _enumeratePath(ISlangMutableFileSystem* fileSystem, const char* path, const ConstArrayView<Entry>& entries) +{ + List<Entry> contents; + + SLANG_RETURN_ON_FAIL(fileSystem->enumeratePathContents(path, _entryCallback, (void*)&contents)); + + contents.sort(); + + if (contents.getArrayView() != entries) + { + return SLANG_FAIL; + } + + return SLANG_OK; +} + +static SlangResult _test(FileSystemType type) +{ + ComPtr<ISlangMutableFileSystem> fileSystem; + + switch (type) + { + case FileSystemType::Zip: + { + SLANG_RETURN_ON_FAIL(ZipFileSystem::create(fileSystem)); + break; + } + case FileSystemType::RiffUncompressed: + { + fileSystem = new RiffFileSystem(nullptr); + break; + } + case FileSystemType::RiffDeflate: + { + fileSystem = new RiffFileSystem(DeflateCompressionSystem::getSingleton()); + break; + } + case FileSystemType::RiffLZ4: + { + fileSystem = new RiffFileSystem(LZ4CompressionSystem::getSingleton()); + break; + } + case FileSystemType::Relative: + { + ComPtr<ISlangMutableFileSystem> memoryFileSystem(new RiffFileSystem(nullptr)); + memoryFileSystem->createDirectory("base"); + + fileSystem = new RelativeFileSystem(memoryFileSystem, "base"); + break; + } + } + + + SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "a", "someText")); + SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "b", "A longer bit of text....")); + + SLANG_RETURN_ON_FAIL(_createAndCheckDirectory(fileSystem, "d")); + SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "d/a", "Some more silly stuff")); + SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "d\\b", "Lets go empty")); + + // Lets find all the files in the directory + + { + const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" } }; + SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView(entries))); + } + + { + const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" }, {SLANG_PATH_TYPE_DIRECTORY, "d" } }; + SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, ".", makeConstArrayView(entries))); + } + + SLANG_RETURN_ON_FAIL(fileSystem->remove("d/a")); + { + const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "b" } }; + SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView(entries))); + } + SLANG_RETURN_ON_FAIL(fileSystem->remove("d\\b")); + { + SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView((const Entry*)nullptr, 0))); + } + + // If it's removed it can't be removed again + SLANG_CHECK(SLANG_FAILED(fileSystem->remove("d\\b"))); + + // Remove the directory + SLANG_RETURN_ON_FAIL(fileSystem->remove("d")); + + { + const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" } }; + SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, ".", makeConstArrayView(entries))); + } + + return SLANG_OK; +} + +SLANG_UNIT_TEST(fileSystem) +{ + for (Index i = 0; i < Count(FileSystemType::CountOf); ++i) + { + const auto type = FileSystemType(i); + + auto const res = _test(type); + + SLANG_CHECK(SLANG_SUCCEEDED(res)); + } +} + |
