Skip to content

Commit

Permalink
Improve robustness of unit tests
Browse files Browse the repository at this point in the history
- Remove dependencies of MaterialXTest on the current working directory, allowing it to be launched from any location.
- Use getDefaultDataSearchPath to access search paths in MaterialXTest, aligning its behavior with that of other applications.
- Merge the concepts of library and source search paths in render testing.
  • Loading branch information
jstone-lucasfilm committed May 31, 2023
1 parent 99ebdf5 commit a9e06a4
Show file tree
Hide file tree
Showing 25 changed files with 195 additions and 237 deletions.
9 changes: 9 additions & 0 deletions source/MaterialXRenderOsl/OslRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ void OslRenderer::renderOSL(const FilePath& dirPath, const string& shaderName, c
" does not include proper tokens for rendering");
}

// Set the working directory for rendering.
FileSearchPath searchPath = getDefaultDataSearchPath();
FilePath rootPath = searchPath.isEmpty() ? FilePath() : searchPath[0];
FilePath origWorkingPath = FilePath::getCurrentPath();
rootPath.setCurrentPath();

// Write scene file
const string sceneFileName("scene_template.xml");
std::ofstream shaderFileStream;
Expand Down Expand Up @@ -178,6 +184,9 @@ void OslRenderer::renderOSL(const FilePath& dirPath, const string& shaderName, c
}
}

// Restore the working directory after rendering.
origWorkingPath.setCurrentPath();

// Report errors on a non-zero return value.
if (returnValue)
{
Expand Down
16 changes: 1 addition & 15 deletions source/MaterialXTest/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ namespace mx = MaterialX;
int main(int argc, char* const argv[])
{
Catch::Session session;

#ifndef _DEBUG
session.configData().showDurations = Catch::ShowDurations::Always;
#endif

#ifdef CATCH_PLATFORM_WINDOWS
BOOL inDebugger = IsDebuggerPresent();
if (inDebugger)
Expand All @@ -29,18 +27,6 @@ int main(int argc, char* const argv[])
}
#endif

// If the current path has no valid resources folder, as can occur when launching the
// test suite from an IDE, then align the current path with the module path.
mx::FilePath resourcesPath = mx::FilePath::getCurrentPath() / "resources";
if (!resourcesPath.exists())
{
resourcesPath = mx::FilePath::getModulePath().getParentPath() / "resources";
if (resourcesPath.exists())
{
resourcesPath.getParentPath().setCurrentPath();
}
}

int returnCode = session.applyCommandLine(argc, argv);
if (returnCode != 0)
{
Expand Down
23 changes: 12 additions & 11 deletions source/MaterialXTest/MaterialXCore/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,24 @@ TEST_CASE("Document", "[document]")

TEST_CASE("Version", "[document]")
{
mx::DocumentPtr doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_ng.mtlx"), doc);
mx::FileSearchPath searchPath("resources/Materials/TestSuite/stdlib/upgrade/");
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr stdlib = mx::createDocument();
mx::loadLibraries({ "libraries" }, searchPath, stdlib);
searchPath.append(searchPath.find("resources/Materials/TestSuite/stdlib/upgrade"));

// 1.36 to 1.37
{
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, "1_36_to_1_37.mtlx", searchPath);
doc->importLibrary(stdlib);
REQUIRE(doc->validate());

mx::XmlWriteOptions writeOptions;
writeOptions.writeXIncludeEnable = true;
mx::writeToXmlFile(doc, "1_36_to_1_37_updated.mtlx", &writeOptions);
std::string xmlString = mx::writeToXmlString(doc, &writeOptions);

mx::DocumentPtr doc2 = mx::createDocument();
mx::readFromXmlFile(doc2, "1_36_to_1_37_updated.mtlx");
mx::readFromXmlString(doc2, xmlString);
REQUIRE(doc2->validate());

// Check conversion to desired types occurred
Expand Down Expand Up @@ -160,18 +162,17 @@ TEST_CASE("Version", "[document]")

// 1.37 to 1.38
{
doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_ng.mtlx"), doc);
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, "1_37_to_1_38.mtlx", searchPath);
doc->importLibrary(stdlib);
REQUIRE(doc->validate());

mx::XmlWriteOptions writeOptions;
writeOptions.writeXIncludeEnable = false;
mx::writeToXmlFile(doc, "1_37_to_1_38_updated.mtlx", &writeOptions);
std::string xmlString = mx::writeToXmlString(doc, &writeOptions);

mx::DocumentPtr doc2 = mx::createDocument();
mx::readFromXmlFile(doc2, "1_37_to_1_38_updated.mtlx");
mx::readFromXmlString(doc2, xmlString);
REQUIRE(doc2->validate());

// atan2 test
Expand Down
7 changes: 2 additions & 5 deletions source/MaterialXTest/MaterialXCore/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,9 @@ TEST_CASE("Material", "[material]")

TEST_CASE("Material Discovery", "[material]")
{
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();

const mx::FilePath currentPath = mx::FilePath::getCurrentPath();
mx::FileSearchPath searchPath(currentPath / mx::FilePath("resources/Materials/TestSuite"));
mx::FilePath filename = "stdlib/materials/material_node_discovery.mtlx";
mx::readFromXmlFile(doc, filename, searchPath);
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/materials/material_node_discovery.mtlx", searchPath);

// 1. Find all materials referenced by material assignments
// which are found in connected nodegraphs
Expand Down
30 changes: 14 additions & 16 deletions source/MaterialXTest/MaterialXCore/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ TEST_CASE("Node", "[node]")
TEST_CASE("Flatten", "[nodegraph]")
{
// Read an example containing graph-based custom nodes.
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/shader/surface.mtlx");
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/shader/surface.mtlx", searchPath);
REQUIRE(doc->validate());

// Count root-level, nested, and custom nodes.
Expand Down Expand Up @@ -174,8 +175,8 @@ TEST_CASE("Flatten", "[nodegraph]")

TEST_CASE("Inheritance", "[nodedef]")
{
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();
mx::FileSearchPath searchPath(mx::FilePath::getCurrentPath());
mx::loadLibraries({ "libraries" }, searchPath, doc);
REQUIRE(doc->validate());
auto nodedef = doc->getNodeDef("ND_standard_surface_surfaceshader");
Expand Down Expand Up @@ -559,13 +560,12 @@ TEST_CASE("Organization", "[nodegraph]")

TEST_CASE("Tokens", "[nodegraph]")
{
mx::DocumentPtr doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_ng.mtlx"), doc);
mx::FileSearchPath searchPath("resources/Materials/TestSuite/stdlib/texture/");
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr stdlib = mx::createDocument();
mx::loadLibraries({ "libraries" }, searchPath, stdlib);

mx::readFromXmlFile(doc, "tokenGraph.mtlx", searchPath);
doc->validate();
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/texture/tokenGraph.mtlx", searchPath);

mx::StringVec graphNames = { "Tokenized_Image_2k_png", "Tokenized_Image_4k_jpg" };
mx::StringVec resolutionStrings = { "2k", "4k" };
Expand Down Expand Up @@ -597,13 +597,13 @@ TEST_CASE("Tokens", "[nodegraph]")

TEST_CASE("Node Definition Creation", "[nodedef]")
{
mx::DocumentPtr doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_ng.mtlx"), doc);
mx::FileSearchPath searchPath("resources/Materials/TestSuite/stdlib/definition/");
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr stdlib = mx::createDocument();
mx::loadLibraries({ "libraries" }, searchPath, stdlib);

mx::readFromXmlFile(doc, "definition_from_nodegraph.mtlx", searchPath);
REQUIRE(doc->validate());
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/definition/definition_from_nodegraph.mtlx", searchPath);
doc->importLibrary(stdlib);

mx::NodeGraphPtr graph = doc->getNodeGraph("test_colorcorrect");
REQUIRE(graph);
Expand Down Expand Up @@ -721,7 +721,5 @@ TEST_CASE("Node Definition Creation", "[nodedef]")
}
REQUIRE(findDefault);
}

REQUIRE(doc->validate());
mx::writeToXmlFile(doc, "definition_from_nodegraph_out.mtlx");
}
9 changes: 2 additions & 7 deletions source/MaterialXTest/MaterialXCore/Traversal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,9 @@ TEST_CASE("IntraGraph Traversal", "[traversal]")

TEST_CASE("InterGraph Traversal", "[traversal]")
{
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();
mx::FilePath currentPath = mx::FilePath::getCurrentPath();
mx::FileSearchPath searchPath(currentPath);
mx::loadLibraries({ "libraries" }, searchPath, doc);

mx::FilePath testFile = currentPath / mx::FilePath("resources/Materials/TestSuite/stdlib/nodegraph_inputs/nodegraph_nodegraph.mtlx");
mx::readFromXmlFile(doc, testFile, searchPath);
REQUIRE(doc->validate());
mx::readFromXmlFile(doc, "resources/Materials/TestSuite/stdlib/nodegraph_inputs/nodegraph_nodegraph.mtlx", searchPath);

for (mx::NodeGraphPtr graph : doc->getNodeGraphs())
{
Expand Down
28 changes: 17 additions & 11 deletions source/MaterialXTest/MaterialXCore/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ const float EPSILON = 1e-4f;

TEST_CASE("UnitAttribute", "[unit]")
{
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibraries({ "libraries" }, searchPath, doc);

std::vector<mx::UnitTypeDefPtr> unitTypeDefs = doc->getUnitTypeDefs();
REQUIRE(!unitTypeDefs.empty());

Expand Down Expand Up @@ -60,8 +62,9 @@ TEST_CASE("UnitAttribute", "[unit]")

TEST_CASE("UnitEvaluation", "[unit]")
{
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr doc = mx::createDocument();
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
mx::loadLibraries({ "libraries" }, searchPath, doc);

//
// Test distance converter
Expand Down Expand Up @@ -117,11 +120,11 @@ TEST_CASE("UnitEvaluation", "[unit]")

TEST_CASE("UnitDocument", "[unit]")
{
mx::FilePath libraryPath("libraries/stdlib");
mx::FilePath examplesPath("resources/Materials/TestSuite/stdlib/units");
std::string searchPath = libraryPath.asString() +
mx::PATH_LIST_SEPARATOR +
examplesPath.asString();
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::DocumentPtr stdlib = mx::createDocument();
mx::loadLibraries({ "libraries" }, searchPath, stdlib);
mx::FilePath examplesPath = searchPath.find("resources/Materials/TestSuite/stdlib/units");
searchPath.append(examplesPath);

static const std::string DISTANCE_DEFAULT("meter");

Expand All @@ -130,7 +133,7 @@ TEST_CASE("UnitDocument", "[unit]")
{
mx::DocumentPtr doc = mx::createDocument();
mx::readFromXmlFile(doc, filename, searchPath);
mx::loadLibrary(mx::FilePath::getCurrentPath() / mx::FilePath("libraries/stdlib/stdlib_defs.mtlx"), doc);
doc->importLibrary(stdlib);

mx::UnitTypeDefPtr distanceTypeDef = doc->getUnitTypeDef("distance");
REQUIRE(distanceTypeDef);
Expand All @@ -149,11 +152,14 @@ TEST_CASE("UnitDocument", "[unit]")
mx::NodePtr pNode = elem->asA<mx::Node>();
if (pNode)
{
if (pNode->getInputCount()) {
for (mx::InputPtr input : pNode->getInputs()) {
if (pNode->getInputCount())
{
for (mx::InputPtr input : pNode->getInputs())
{
const std::string type = input->getType();
const mx::ValuePtr value = input->getValue();
if (input->hasUnit() && value) {
if (input->hasUnit() && value)
{
if (type == "float")
{
float originalval = value->asA<float>();
Expand Down
29 changes: 11 additions & 18 deletions source/MaterialXTest/MaterialXFormat/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,27 @@ TEST_CASE("Syntactic operations", "[file]")

TEST_CASE("File system operations", "[file]")
{
mx::StringVec filenames =
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::FilePathVec examplePaths =
{
"libraries/stdlib/stdlib_defs.mtlx",
"resources/Materials/Examples/StandardSurface/standard_surface_brass_tiled.mtlx",
"resources/Materials/Examples/StandardSurface/standard_surface_marble_solid.mtlx",
};

for (const std::string& filename : filenames)
for (const mx::FilePath& path : examplePaths)
{
mx::FilePath path(filename);
REQUIRE(path.exists());
REQUIRE(mx::FileSearchPath().find(path).exists());
REQUIRE(searchPath.find(path).exists());
}

mx::FilePath currentPath = mx::FilePath::getCurrentPath();
mx::FilePath modulePath = mx::FilePath::getModulePath();
bool expectedPaths = currentPath == modulePath ||
currentPath == modulePath.getParentPath();
REQUIRE(expectedPaths);
REQUIRE(mx::FilePath::getCurrentPath().exists());
REQUIRE(mx::FilePath::getModulePath().exists());
}

TEST_CASE("File search path operations", "[file]")
{
mx::FileSearchPath searchPath = "libraries/stdlib" +
mx::PATH_LIST_SEPARATOR +
"resources/Materials/Examples/StandardSurface";
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
searchPath.append(searchPath.find("libraries/stdlib"));
searchPath.append(searchPath.find("resources/Materials/Examples/StandardSurface"));

mx::FilePathVec filenames =
{
Expand Down Expand Up @@ -102,10 +97,8 @@ TEST_CASE("Flatten filenames", "[file]")
image2->setInputValue("file", "brass_color.jpg", mx::FILENAME_TYPE_STRING);

// 2. Test resolving to absolute paths
mx::FilePath rootPath(mx::FilePath::getCurrentPath());

mx::FileSearchPath searchPath;
searchPath.append(rootPath);
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::FilePath rootPath = searchPath.isEmpty() ? mx::FilePath() : searchPath[0];

mx::flattenFilenames(doc1, searchPath);
REQUIRE(nodeGraph->getFilePrefix() == mx::EMPTY_STRING);
Expand Down
13 changes: 7 additions & 6 deletions source/MaterialXTest/MaterialXFormat/XmlIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ namespace mx = MaterialX;

TEST_CASE("Load content", "[xmlio]")
{
mx::FilePath libraryPath("libraries/stdlib");
mx::FilePath examplesPath("resources/Materials/Examples/StandardSurface");
mx::FileSearchPath searchPath = libraryPath.asString() +
mx::PATH_LIST_SEPARATOR +
examplesPath.asString();
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::FilePath libraryPath = searchPath.find("libraries/stdlib");
mx::FilePath examplesPath = searchPath.find("resources/Materials/Examples/StandardSurface");
searchPath.append(libraryPath);
searchPath.append(examplesPath);

// Read the standard library.
std::vector<mx::DocumentPtr> libs;
Expand Down Expand Up @@ -242,7 +242,8 @@ TEST_CASE("Load content", "[xmlio]")

TEST_CASE("Comments and newlines", "[xmlio]")
{
mx::FilePath testPath("resources/Materials/Examples/StandardSurface/standard_surface_chess_set.mtlx");
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
mx::FilePath testPath = searchPath.find("resources/Materials/Examples/StandardSurface/standard_surface_chess_set.mtlx");

// Read the example file into an XML string buffer.
std::string origXml = mx::readFile(testPath);
Expand Down
Loading

0 comments on commit a9e06a4

Please sign in to comment.