Slang seperation
This commit is contained in:
203
tests/ShaderCompilerLookupTests.cpp
Normal file
203
tests/ShaderCompilerLookupTests.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "ShaderCompiler.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const std::string& message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
++gFailures;
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
}
|
||||
|
||||
std::filesystem::path MakeTestRoot(const std::string& name)
|
||||
{
|
||||
const std::filesystem::path root =
|
||||
std::filesystem::temp_directory_path() /
|
||||
("shader-compiler-lookup-" + name + "-" + std::to_string(std::filesystem::file_time_type::clock::now().time_since_epoch().count()));
|
||||
std::filesystem::create_directories(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
void WriteFakeSlangCompiler(const std::filesystem::path& path)
|
||||
{
|
||||
std::filesystem::create_directories(path.parent_path());
|
||||
std::ofstream output(path, std::ios::binary);
|
||||
output << "not a real compiler";
|
||||
}
|
||||
|
||||
std::string ReadEnvironmentVariable(const char* name)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
char* value = nullptr;
|
||||
std::size_t size = 0;
|
||||
if (_dupenv_s(&value, &size, name) != 0 || value == nullptr)
|
||||
return std::string();
|
||||
std::string text(value);
|
||||
std::free(value);
|
||||
return text;
|
||||
#else
|
||||
const char* value = std::getenv(name);
|
||||
return value ? std::string(value) : std::string();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WriteEnvironmentVariable(const char* name, const std::string& value)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
_putenv_s(name, value.c_str());
|
||||
#else
|
||||
if (value.empty())
|
||||
unsetenv(name);
|
||||
else
|
||||
setenv(name, value.c_str(), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
class ScopedEnvironmentVariable
|
||||
{
|
||||
public:
|
||||
ScopedEnvironmentVariable(const char* name, const std::string& value) :
|
||||
mName(name),
|
||||
mOriginal(ReadEnvironmentVariable(name))
|
||||
{
|
||||
WriteEnvironmentVariable(name, value);
|
||||
}
|
||||
|
||||
~ScopedEnvironmentVariable()
|
||||
{
|
||||
WriteEnvironmentVariable(mName.c_str(), mOriginal);
|
||||
}
|
||||
|
||||
ScopedEnvironmentVariable(const ScopedEnvironmentVariable&) = delete;
|
||||
ScopedEnvironmentVariable& operator=(const ScopedEnvironmentVariable&) = delete;
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mOriginal;
|
||||
};
|
||||
|
||||
bool SamePath(const std::filesystem::path& left, const std::filesystem::path& right)
|
||||
{
|
||||
std::error_code leftError;
|
||||
std::error_code rightError;
|
||||
return std::filesystem::weakly_canonical(left, leftError) == std::filesystem::weakly_canonical(right, rightError);
|
||||
}
|
||||
|
||||
void TestSlangRootWinsOverThirdPartyRoot()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot("slang-root");
|
||||
const std::filesystem::path expected = root / "env-slang" / "bin" / "slangc.exe";
|
||||
const std::filesystem::path thirdPartyCompiler = root / "third-party" / "slang-2026.8-windows-x86_64" / "bin" / "slangc.exe";
|
||||
WriteFakeSlangCompiler(expected);
|
||||
WriteFakeSlangCompiler(thirdPartyCompiler);
|
||||
|
||||
ScopedEnvironmentVariable slangRoot("SLANG_ROOT", (root / "env-slang").string());
|
||||
ScopedEnvironmentVariable thirdPartyRoot("THIRD_PARTY_ROOT", (root / "third-party").string());
|
||||
|
||||
std::filesystem::path actual;
|
||||
std::string error;
|
||||
Expect(ShaderCompiler::FindSlangCompilerPath(root, actual, error), "SLANG_ROOT compiler is found");
|
||||
Expect(SamePath(actual, expected), "SLANG_ROOT has priority over THIRD_PARTY_ROOT");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestThirdPartyRootUsesCMakeBundleLayout()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot("third-party-root");
|
||||
const std::filesystem::path thirdPartyRootPath = root / "video-io-3rdParty";
|
||||
const std::filesystem::path expected = thirdPartyRootPath / "slang-2026.8-windows-x86_64" / "bin" / "slangc.exe";
|
||||
WriteFakeSlangCompiler(expected);
|
||||
|
||||
ScopedEnvironmentVariable slangRoot("SLANG_ROOT", "");
|
||||
ScopedEnvironmentVariable thirdPartyRoot("THIRD_PARTY_ROOT", thirdPartyRootPath.string());
|
||||
|
||||
std::filesystem::path actual;
|
||||
std::string error;
|
||||
Expect(ShaderCompiler::FindSlangCompilerPath(root, actual, error), "THIRD_PARTY_ROOT compiler is found");
|
||||
Expect(SamePath(actual, expected), "THIRD_PARTY_ROOT matches CMake's Slang bundle layout");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestRepoVideoIoBundleWinsOverLegacyRepoBundle()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot("repo-video-io");
|
||||
const std::filesystem::path expected = root / "video-io-3rdParty" / "slang-2026.8-windows-x86_64" / "bin" / "slangc.exe";
|
||||
const std::filesystem::path legacy = root / "3rdParty" / "slang-2026.8-windows-x86_64" / "bin" / "slangc.exe";
|
||||
WriteFakeSlangCompiler(expected);
|
||||
WriteFakeSlangCompiler(legacy);
|
||||
|
||||
ScopedEnvironmentVariable slangRoot("SLANG_ROOT", "");
|
||||
ScopedEnvironmentVariable thirdPartyRoot("THIRD_PARTY_ROOT", "");
|
||||
|
||||
std::filesystem::path actual;
|
||||
std::string error;
|
||||
Expect(ShaderCompiler::FindSlangCompilerPath(root, actual, error), "repo video-io-3rdParty compiler is found");
|
||||
Expect(SamePath(actual, expected), "repo video-io-3rdParty has priority over repo 3rdParty");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestPackagedSlangFolderIsAccepted()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot("packaged");
|
||||
const std::filesystem::path expected = root / "3rdParty" / "slang" / "bin" / "slangc.exe";
|
||||
WriteFakeSlangCompiler(expected);
|
||||
|
||||
ScopedEnvironmentVariable slangRoot("SLANG_ROOT", "");
|
||||
ScopedEnvironmentVariable thirdPartyRoot("THIRD_PARTY_ROOT", "");
|
||||
|
||||
std::filesystem::path actual;
|
||||
std::string error;
|
||||
Expect(ShaderCompiler::FindSlangCompilerPath(root, actual, error), "packaged 3rdParty/slang compiler is found");
|
||||
Expect(SamePath(actual, expected), "packaged Slang install layout is accepted");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
|
||||
void TestLegacyThirdPartyScanStillAcceptsVersionedFolders()
|
||||
{
|
||||
const std::filesystem::path root = MakeTestRoot("legacy-scan");
|
||||
const std::filesystem::path expected = root / "3rdParty" / "slang-custom-build" / "bin" / "slangc.exe";
|
||||
WriteFakeSlangCompiler(expected);
|
||||
|
||||
ScopedEnvironmentVariable slangRoot("SLANG_ROOT", "");
|
||||
ScopedEnvironmentVariable thirdPartyRoot("THIRD_PARTY_ROOT", "");
|
||||
|
||||
std::filesystem::path actual;
|
||||
std::string error;
|
||||
Expect(ShaderCompiler::FindSlangCompilerPath(root, actual, error), "legacy 3rdParty scan finds versioned Slang folders");
|
||||
Expect(SamePath(actual, expected), "legacy scan returns the discovered compiler path");
|
||||
|
||||
std::filesystem::remove_all(root);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestSlangRootWinsOverThirdPartyRoot();
|
||||
TestThirdPartyRootUsesCMakeBundleLayout();
|
||||
TestRepoVideoIoBundleWinsOverLegacyRepoBundle();
|
||||
TestPackagedSlangFolderIsAccepted();
|
||||
TestLegacyThirdPartyScanStillAcceptsVersionedFolders();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " ShaderCompiler lookup test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "ShaderCompiler lookup tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user