/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2021 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include "catch2/catch.hpp" #include #include #include #include using namespace openspace::configuration; namespace { std::string MinimalConfig = R"( Paths = {} )"; void writeConfig(const std::string& filename, const std::string& content) { std::string config = MinimalConfig + content; std::ofstream f(filename); f << MinimalConfig << '\n' << content; } Configuration loadConfiguration(const std::string& tag, const std::string& content) { std::string filename = fmt::format("test_configuration_{}.cfg", tag); std::filesystem::path path = std::filesystem::temp_directory_path(); std::string configFile = (path / filename).string(); writeConfig(configFile, content); Configuration conf = loadConfigurationFromFile(configFile, content); std::filesystem::remove(configFile); return conf; } } // namespace TEST_CASE("Configuration: minimal", "[configuration]") { loadConfiguration("minimal", ""); } TEST_CASE("Configuration: windowConfiguration", "[configuration]") { constexpr const char Extra[] = R"(SGCTConfig = "foobar")"; const Configuration c = loadConfiguration("windowConfiguration", Extra); REQUIRE(c.windowConfiguration == "foobar"); } TEST_CASE("Configuration: asset", "[configuration]") { constexpr const char Extra[] = R"(Asset = "foobar")"; const Configuration c = loadConfiguration("asset", Extra); REQUIRE(c.asset == "foobar"); } TEST_CASE("Configuration: profile", "[configuration]") { constexpr const char Extra[] = R"(Profile = "foobar")"; const Configuration c = loadConfiguration("profile", Extra); REQUIRE(c.profile == "foobar"); } TEST_CASE("Configuration: globalCustomizationScripts", "[configuration]") { constexpr const char Extra[] = R"(GlobalCustomizationScripts = { "foo", "bar" })"; const Configuration c = loadConfiguration("globalCustomization", Extra); REQUIRE(c.globalCustomizationScripts.size() == 2); CHECK(c.globalCustomizationScripts == std::vector{ "foo", "bar" }); } TEST_CASE("Configuration: paths", "[configuration]") { constexpr const char Extra[] = R"(Paths = { foo = "1", bar = "2" })"; const Configuration c = loadConfiguration("paths", Extra); REQUIRE(c.pathTokens.size() == 2); CHECK( c.pathTokens == std::map{ { "foo", "1" }, { "bar", "2" } } ); } TEST_CASE("Configuration: fonts", "[configuration]") { constexpr const char Extra[] = R"(Fonts = { foo = "1", bar = "2" })"; const Configuration c = loadConfiguration("fonts", Extra); REQUIRE(c.fonts.size() == 2); CHECK( c.fonts == std::map{ { "foo", "1" }, { "bar", "2" } } ); } TEST_CASE("Configuration: logging", "[configuration]") { Configuration defaultConf; { // Empty constexpr const char Extra[] = R"(Logging = {})"; const Configuration c = loadConfiguration("logging1", Extra); CHECK(c.logging.level == defaultConf.logging.level); CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush); CHECK( c.logging.capabilitiesVerbosity == defaultConf.logging.capabilitiesVerbosity ); CHECK(c.logging.logs == defaultConf.logging.logs); } { // level constexpr const char Extra[] = R"(Logging = { LogLevel = "Fatal" })"; const Configuration c = loadConfiguration("logging2", Extra); CHECK(c.logging.level == "Fatal"); CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush); CHECK( c.logging.capabilitiesVerbosity == defaultConf.logging.capabilitiesVerbosity ); CHECK(c.logging.logs == defaultConf.logging.logs); } { // forceimmediate constexpr const char Extra[] = R"(Logging = { ImmediateFlush = false })"; const Configuration c = loadConfiguration("logging3", Extra); CHECK(c.logging.level == defaultConf.logging.level); CHECK(c.logging.forceImmediateFlush == false); CHECK( c.logging.capabilitiesVerbosity == defaultConf.logging.capabilitiesVerbosity ); CHECK(c.logging.logs == defaultConf.logging.logs); } { // logs constexpr const char Extra[] = R"( Logging = { Logs = { { Type = "html", File = "foobar", Append = false } } } )"; const Configuration c = loadConfiguration("logging4", Extra); CHECK(c.logging.level == defaultConf.logging.level); CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush); CHECK( c.logging.capabilitiesVerbosity == defaultConf.logging.capabilitiesVerbosity ); REQUIRE(c.logging.logs.size() == 1); const ghoul::Dictionary& d = c.logging.logs[0]; REQUIRE(d.hasValue("Type")); CHECK(d.value("Type") == "html"); REQUIRE(d.hasValue("File")); CHECK(d.value("File") == "foobar"); REQUIRE(d.hasValue("Append")); CHECK(d.value("Append") == false); } { // capabilities verbosity constexpr const char Extra[] = R"(Logging = { CapabilitiesVerbosity = "Full" })"; const Configuration c = loadConfiguration("logging5", Extra); CHECK(c.logging.level == defaultConf.logging.level); CHECK(c.logging.forceImmediateFlush == defaultConf.logging.forceImmediateFlush); CHECK(c.logging.capabilitiesVerbosity == "Full"); CHECK(c.logging.logs == defaultConf.logging.logs); } } TEST_CASE("Configuration: scriptlog", "[configuration]") { constexpr const char Extra[] = R"(ScriptLog = "foobar")"; const Configuration c = loadConfiguration("scriptlog", Extra); CHECK(c.scriptLog == "foobar"); } TEST_CASE("Configuration: documentationpath", "[configuration]") { constexpr const char Extra[] = R"(Documentation = { Path = "foobar" })"; const Configuration c = loadConfiguration("documentationpath", Extra); CHECK(c.documentation.path == "foobar"); } TEST_CASE("Configuration: versioncheckurl", "[configuration]") { constexpr const char Extra[] = R"(VersionCheckUrl = "foobar")"; const Configuration c = loadConfiguration("versioncheckurl", Extra); CHECK(c.versionCheckUrl == "foobar"); } TEST_CASE("Configuration: useMultithreadedInit", "[configuration]") { constexpr const char Extra[] = R"(UseMultithreadedInitialization = true)"; const Configuration c = loadConfiguration("useMultithreadedInit", Extra); CHECK(c.useMultithreadedInitialization == true); } TEST_CASE("Configuration: loadingscreen", "[configuration]") { Configuration defaultConf; { // empty constexpr const char Extra[] = R"(LoadingScreen = {})"; const Configuration c = loadConfiguration("loadingscreen1", Extra); CHECK( c.loadingScreen.isShowingMessages == defaultConf.loadingScreen.isShowingMessages ); CHECK( c.loadingScreen.isShowingProgressbar == defaultConf.loadingScreen.isShowingProgressbar ); CHECK( c.loadingScreen.isShowingNodeNames == defaultConf.loadingScreen.isShowingNodeNames ); } { // isShowingMessages constexpr const char Extra[] = R"(LoadingScreen = { ShowMessage = true })"; const Configuration c = loadConfiguration("loadingscreen2", Extra); CHECK(c.loadingScreen.isShowingMessages == true); CHECK( c.loadingScreen.isShowingProgressbar == defaultConf.loadingScreen.isShowingProgressbar ); CHECK( c.loadingScreen.isShowingNodeNames == defaultConf.loadingScreen.isShowingNodeNames ); } { // isShowingProgressbar constexpr const char Extra[] = R"(LoadingScreen = { ShowProgressbar = true })"; const Configuration c = loadConfiguration("loadingscreen3", Extra); CHECK( c.loadingScreen.isShowingMessages == defaultConf.loadingScreen.isShowingMessages ); CHECK(c.loadingScreen.isShowingProgressbar == true); CHECK( c.loadingScreen.isShowingNodeNames == defaultConf.loadingScreen.isShowingNodeNames ); } { // isShowingNodeNames constexpr const char Extra[] = R"(LoadingScreen = { ShowNodeNames = true })"; const Configuration c = loadConfiguration("loadingscreen4", Extra); CHECK( c.loadingScreen.isShowingMessages == defaultConf.loadingScreen.isShowingMessages ); CHECK( c.loadingScreen.isShowingProgressbar == defaultConf.loadingScreen.isShowingProgressbar ); CHECK(c.loadingScreen.isShowingNodeNames == true); } } TEST_CASE("Configuration: isCheckingOpenGLState", "[configuration]") { constexpr const char Extra[] = R"(CheckOpenGLState = true)"; const Configuration c = loadConfiguration("isCheckingOpenGLState", Extra); CHECK(c.isCheckingOpenGLState == true); } TEST_CASE("Configuration: isLoggingOpenGLCalls", "[configuration]") { constexpr const char Extra[] = R"(LogEachOpenGLCall = true)"; const Configuration c = loadConfiguration("isLoggingOpenGLCalls", Extra); CHECK(c.isLoggingOpenGLCalls == true); } TEST_CASE("Configuration: shutdownCountdown", "[configuration]") { constexpr const char Extra[] = R"(ShutdownCountdown = 0.5)"; const Configuration c = loadConfiguration("shutdownCountdown", Extra); CHECK(c.shutdownCountdown == 0.5f); } TEST_CASE("Configuration: shouldUseScreenshotDate", "[configuration]") { constexpr const char Extra[] = R"(ScreenshotUseDate = true)"; const Configuration c = loadConfiguration("shouldUseScreenshotDate", Extra); CHECK(c.shouldUseScreenshotDate == true); } TEST_CASE("Configuration: onScreenTextScaling", "[configuration]") { constexpr const char Extra[] = R"(OnScreenTextScaling = "framebuffer")"; const Configuration c = loadConfiguration("onScreenTextScaling", Extra); CHECK(c.onScreenTextScaling == "framebuffer"); } TEST_CASE("Configuration: usePerProfileCache", "[configuration]") { constexpr const char Extra[] = R"(PerProfileCache = true)"; const Configuration c = loadConfiguration("usePerProfileCache", Extra); CHECK(c.usePerProfileCache == true); } TEST_CASE("Configuration: isRenderingOnMasterDisabled", "[configuration]") { constexpr const char Extra[] = R"(DisableRenderingOnMaster = true)"; const Configuration c = loadConfiguration("isRenderingOnMasterDisabled", Extra); CHECK(c.isRenderingOnMasterDisabled == true); } TEST_CASE("Configuration: globalRotation", "[configuration]") { constexpr const char Extra[] = R"(GlobalRotation = { 1.0, 2.0, 3.0 })"; const Configuration c = loadConfiguration("globalRotation", Extra); CHECK(c.globalRotation == glm::vec3(1.0, 2.0, 3.0)); } TEST_CASE("Configuration: screenSpaceRotation", "[configuration]") { constexpr const char Extra[] = R"(ScreenSpaceRotation = { 1.0, 2.0, 3.0 })"; const Configuration c = loadConfiguration("screenSpaceRotation", Extra); CHECK(c.screenSpaceRotation == glm::vec3(1.0, 2.0, 3.0)); } TEST_CASE("Configuration: masterRotation", "[configuration]") { constexpr const char Extra[] = R"(MasterRotation = { 1.0, 2.0, 3.0 })"; const Configuration c = loadConfiguration("masterRotation", Extra); CHECK(c.masterRotation == glm::vec3(1.0, 2.0, 3.0)); } TEST_CASE("Configuration: isConsoleDisabled", "[configuration]") { constexpr const char Extra[] = R"(DisableInGameConsole = true)"; const Configuration c = loadConfiguration("isConsoleDisabled", Extra); CHECK(c.isConsoleDisabled == true); } TEST_CASE("Configuration: bypassLauncher", "[configuration]") { constexpr const char Extra[] = R"(BypassLauncher = true)"; const Configuration c = loadConfiguration("bypassLauncher", Extra); CHECK(c.bypassLauncher == true); } TEST_CASE("Configuration: moduleConfigurations", "[configuration]") { { // empty constexpr const char Extra[] = R"(ModuleConfigurations = {})"; const Configuration c = loadConfiguration("moduleConfigurations", Extra); CHECK(c.moduleConfigurations.empty()); } { // values constexpr const char Extra[] = R"( ModuleConfigurations = { Foo = { Foo2 = 1.0, Foo3 = "abc" }, Bar = { Bar2 = true, Bar3 = { 1.0, 2.0, 3.0 } } } )"; const Configuration c = loadConfiguration("moduleConfigurations", Extra); REQUIRE(c.moduleConfigurations.size() == 2); ghoul::Dictionary foo = c.moduleConfigurations.at("Foo"); REQUIRE(foo.size() == 2); REQUIRE(foo.hasValue("Foo2")); CHECK(foo.value("Foo2") == 1.0); REQUIRE(foo.hasValue("Foo3")); CHECK(foo.value("Foo3") == std::string("abc")); ghoul::Dictionary bar = c.moduleConfigurations.at("Bar"); REQUIRE(bar.size() == 2); REQUIRE(bar.hasValue("Bar2")); CHECK(bar.value("Bar2") == true); REQUIRE(bar.hasValue("Bar3")); CHECK(bar.value("Bar3") == glm::dvec3(1.0, 2.0, 3.0)); } } TEST_CASE("Configuration: openGLDebugContext", "[configuration]") { Configuration defaultConf; { // empty-ish / activate constexpr const char Extra[] = R"(OpenGLDebugContext = { Activate = true })"; const Configuration c = loadConfiguration("openGLDebugContext1", Extra); CHECK(c.openGLDebugContext.isActive == true); CHECK(c.openGLDebugContext.printStacktrace == false); CHECK( c.openGLDebugContext.isSynchronous == defaultConf.openGLDebugContext.isSynchronous ); REQUIRE( c.openGLDebugContext.identifierFilters.size() == defaultConf.openGLDebugContext.identifierFilters.size() ); for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) { CHECK( c.openGLDebugContext.identifierFilters[i].identifier == defaultConf.openGLDebugContext.identifierFilters[i].identifier ); CHECK( c.openGLDebugContext.identifierFilters[i].source == defaultConf.openGLDebugContext.identifierFilters[i].source ); CHECK( c.openGLDebugContext.identifierFilters[i].type == defaultConf.openGLDebugContext.identifierFilters[i].type ); } CHECK( c.openGLDebugContext.severityFilters == defaultConf.openGLDebugContext.severityFilters ); } { // isSynchronous constexpr const char Extra[] = R"( OpenGLDebugContext = { Activate = true, Synchronous = true } )"; const Configuration c = loadConfiguration("openGLDebugContext2", Extra); CHECK(c.openGLDebugContext.isActive == true); CHECK(c.openGLDebugContext.isSynchronous == true); REQUIRE( c.openGLDebugContext.identifierFilters.size() == defaultConf.openGLDebugContext.identifierFilters.size() ); for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) { CHECK( c.openGLDebugContext.identifierFilters[i].identifier == defaultConf.openGLDebugContext.identifierFilters[i].identifier ); CHECK( c.openGLDebugContext.identifierFilters[i].source == defaultConf.openGLDebugContext.identifierFilters[i].source ); CHECK( c.openGLDebugContext.identifierFilters[i].type == defaultConf.openGLDebugContext.identifierFilters[i].type ); } CHECK( c.openGLDebugContext.severityFilters == defaultConf.openGLDebugContext.severityFilters ); } { // identifierFilters constexpr const char Extra[] = R"( OpenGLDebugContext = { Activate = true, PrintStacktrace = true, FilterIdentifier = { { Identifier = 1, Source = "API", Type = "Error" }, { Identifier = 2, Source = "Window System", Type = "Deprecated" }, { Identifier = 3, Source = "Shader Compiler", Type = "Undefined" }, { Identifier = 4, Source = "Third Party", Type = "Portability" }, { Identifier = 5, Source = "Application", Type = "Performance" }, { Identifier = 6, Source = "Other", Type = "Marker" }, { Identifier = 7, Source = "Don't care", Type = "Push group" }, { Identifier = 8, Source = "API", Type = "Pop group" }, { Identifier = 9, Source = "Window System", Type = "Other" }, { Identifier = 10, Source = "Shader Compiler", Type = "Don't care" } } } )"; const Configuration c = loadConfiguration("openGLDebugContext3", Extra); CHECK(c.openGLDebugContext.isActive == true); CHECK(c.openGLDebugContext.printStacktrace == true); CHECK( c.openGLDebugContext.isSynchronous == defaultConf.openGLDebugContext.isSynchronous ); REQUIRE(c.openGLDebugContext.identifierFilters.size() == 10); CHECK(c.openGLDebugContext.identifierFilters[0].identifier == 1); CHECK(c.openGLDebugContext.identifierFilters[0].source == "API"); CHECK(c.openGLDebugContext.identifierFilters[0].type == "Error"); CHECK(c.openGLDebugContext.identifierFilters[1].identifier == 2); CHECK(c.openGLDebugContext.identifierFilters[1].source == "Window System"); CHECK(c.openGLDebugContext.identifierFilters[1].type == "Deprecated"); CHECK(c.openGLDebugContext.identifierFilters[2].identifier == 3); CHECK(c.openGLDebugContext.identifierFilters[2].source == "Shader Compiler"); CHECK(c.openGLDebugContext.identifierFilters[2].type == "Undefined"); CHECK(c.openGLDebugContext.identifierFilters[3].identifier == 4); CHECK(c.openGLDebugContext.identifierFilters[3].source == "Third Party"); CHECK(c.openGLDebugContext.identifierFilters[3].type == "Portability"); CHECK(c.openGLDebugContext.identifierFilters[4].identifier == 5); CHECK(c.openGLDebugContext.identifierFilters[4].source == "Application"); CHECK(c.openGLDebugContext.identifierFilters[4].type == "Performance"); CHECK(c.openGLDebugContext.identifierFilters[5].identifier == 6); CHECK(c.openGLDebugContext.identifierFilters[5].source == "Other"); CHECK(c.openGLDebugContext.identifierFilters[5].type == "Marker"); CHECK(c.openGLDebugContext.identifierFilters[6].identifier == 7); CHECK(c.openGLDebugContext.identifierFilters[6].source == "Don't care"); CHECK(c.openGLDebugContext.identifierFilters[6].type == "Push group"); CHECK(c.openGLDebugContext.identifierFilters[7].identifier == 8); CHECK(c.openGLDebugContext.identifierFilters[7].source == "API"); CHECK(c.openGLDebugContext.identifierFilters[7].type == "Pop group"); CHECK(c.openGLDebugContext.identifierFilters[8].identifier == 9); CHECK(c.openGLDebugContext.identifierFilters[8].source == "Window System"); CHECK(c.openGLDebugContext.identifierFilters[8].type == "Other"); CHECK(c.openGLDebugContext.identifierFilters[9].identifier == 10); CHECK(c.openGLDebugContext.identifierFilters[9].source == "Shader Compiler"); CHECK(c.openGLDebugContext.identifierFilters[9].type == "Don't care"); CHECK( c.openGLDebugContext.severityFilters == defaultConf.openGLDebugContext.severityFilters ); } { // filterSeverity constexpr const char Extra[] = R"( OpenGLDebugContext = { Activate = true, FilterSeverity = { "High", "Medium" } } )"; const Configuration c = loadConfiguration("openGLDebugContext4", Extra); CHECK(c.openGLDebugContext.isActive == true); CHECK(c.openGLDebugContext.printStacktrace == false); CHECK( c.openGLDebugContext.isSynchronous == defaultConf.openGLDebugContext.isSynchronous ); REQUIRE( c.openGLDebugContext.identifierFilters.size() == defaultConf.openGLDebugContext.identifierFilters.size() ); for (size_t i = 0; i < c.openGLDebugContext.identifierFilters.size(); i += 1) { CHECK( c.openGLDebugContext.identifierFilters[i].identifier == defaultConf.openGLDebugContext.identifierFilters[i].identifier ); CHECK( c.openGLDebugContext.identifierFilters[i].source == defaultConf.openGLDebugContext.identifierFilters[i].source ); CHECK( c.openGLDebugContext.identifierFilters[i].type == defaultConf.openGLDebugContext.identifierFilters[i].type ); } REQUIRE(c.openGLDebugContext.severityFilters.size() == 2); CHECK( c.openGLDebugContext.severityFilters == std::vector{ "High", "Medium" } ); } } TEST_CASE("Configuration: httpProxy", "[configuration]") { Configuration defaultConf; { // empty-ish / address + port constexpr const char Extra[] = R"( HttpProxy = { Address = "foobar", Port = 1234 } )"; const Configuration c = loadConfiguration("httpProxy1", Extra); CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy); CHECK(c.httpProxy.address == "foobar"); CHECK(c.httpProxy.port == 1234); CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication); CHECK(c.httpProxy.user == defaultConf.httpProxy.user); CHECK(c.httpProxy.password == defaultConf.httpProxy.password); } { // activate constexpr const char Extra[] = R"( HttpProxy = { Activate = true, Address = "foobar", Port = 1234 } )"; const Configuration c = loadConfiguration("httpProxy2", Extra); CHECK(c.httpProxy.usingHttpProxy == true); CHECK(c.httpProxy.address == "foobar"); CHECK(c.httpProxy.port == 1234); CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication); CHECK(c.httpProxy.user == defaultConf.httpProxy.user); CHECK(c.httpProxy.password == defaultConf.httpProxy.password); } { // authentication constexpr const char Extra[] = R"( HttpProxy = { Address = "foobar", Port = 1234, Authentication = "ntlm" } )"; const Configuration c = loadConfiguration("httpProxy3", Extra); CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy); CHECK(c.httpProxy.address == "foobar"); CHECK(c.httpProxy.port == 1234); CHECK(c.httpProxy.authentication == "ntlm"); CHECK(c.httpProxy.user == defaultConf.httpProxy.user); CHECK(c.httpProxy.password == defaultConf.httpProxy.password); } { // user constexpr const char Extra[] = R"( HttpProxy = { Address = "foobar", Port = 1234, User = "user-bar" } )"; const Configuration c = loadConfiguration("httpProxy4", Extra); CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy); CHECK(c.httpProxy.address == "foobar"); CHECK(c.httpProxy.port == 1234); CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication); CHECK(c.httpProxy.user == "user-bar"); CHECK(c.httpProxy.password == defaultConf.httpProxy.password); } { // password constexpr const char Extra[] = R"( HttpProxy = { Address = "foobar", Port = 1234, Password = "password-bar" } )"; const Configuration c = loadConfiguration("httpProxy5", Extra); CHECK(c.httpProxy.usingHttpProxy == defaultConf.httpProxy.usingHttpProxy); CHECK(c.httpProxy.address == "foobar"); CHECK(c.httpProxy.port == 1234); CHECK(c.httpProxy.authentication == defaultConf.httpProxy.authentication); CHECK(c.httpProxy.user == defaultConf.httpProxy.user); CHECK(c.httpProxy.password == "password-bar"); } }