mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 03:53:26 -08:00
[Server] Add per-run configuration overrides (#7820)
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / vcpkg baseline (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Fedora 45 release (push) Blocked by required conditions
Build Desktop / Fedora 45 debug (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 sanitize (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 27 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / vcpkg baseline (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Fedora 45 release (push) Blocked by required conditions
Build Desktop / Fedora 45 debug (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 sanitize (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 cover (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 27 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / Prune caches (push) Waiting to run
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Add --set key=value to override a section-qualified scalar configuration key for a single run and --print-config to print the effective configuration, with secrets redacted. SettingsCache owns the override map, so reads see the override without rewriting the ini file, and rebuilds the disallowed-name regexps when users/disallowedregexp is overridden. Bare keys and array-scoped keys are rejected because array loops read them relative to the active group, where a full-key override would either be ignored or rewrite every entry. Cover the ini, default, override, override-only-key, regexp-rebuild, secret-redaction, and parse paths with a server-labelled gtest.
This commit is contained in:
parent
ccda73fe5c
commit
214b284814
5 changed files with 340 additions and 0 deletions
162
tests/settings/servatrice_settings_test.cpp
Normal file
162
tests/settings/servatrice_settings_test.cpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#include "settingscache.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* QSettings' path helpers and the portable-mode probe need a QCoreApplication.
|
||||
* The test binary keeps one alive for the whole process.
|
||||
*/
|
||||
QCoreApplication &testApplication()
|
||||
{
|
||||
static int argc = 1;
|
||||
static char name[] = "servatrice_settings_test";
|
||||
static char *argv[] = {name, nullptr};
|
||||
static QCoreApplication application(argc, argv);
|
||||
return application;
|
||||
}
|
||||
|
||||
class ServatriceSettingsTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
QTemporaryDir dir;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
testApplication();
|
||||
ASSERT_TRUE(dir.isValid());
|
||||
}
|
||||
|
||||
QString configPath() const
|
||||
{
|
||||
return dir.filePath(QStringLiteral("servatrice.ini"));
|
||||
}
|
||||
|
||||
void writeConfig(const QByteArray &contents) const
|
||||
{
|
||||
QFile file(configPath());
|
||||
ASSERT_TRUE(file.open(QIODevice::WriteOnly | QIODevice::Text));
|
||||
ASSERT_EQ(file.write(contents), contents.size());
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_F(ServatriceSettingsTest, ReadsValueFromIni)
|
||||
{
|
||||
writeConfig("[server]\nport=4747\n");
|
||||
SettingsCache settings(configPath());
|
||||
|
||||
EXPECT_EQ(settings.value("server/port").toInt(), 4747);
|
||||
}
|
||||
|
||||
TEST_F(ServatriceSettingsTest, MissingKeyFallsBackToDefault)
|
||||
{
|
||||
writeConfig("[server]\nport=4747\n");
|
||||
SettingsCache settings(configPath());
|
||||
|
||||
EXPECT_EQ(settings.value("server/missing", 1234).toInt(), 1234);
|
||||
}
|
||||
|
||||
TEST_F(ServatriceSettingsTest, OverrideWinsWithoutTouchingTheFile)
|
||||
{
|
||||
writeConfig("[server]\nport=4747\n");
|
||||
SettingsCache settings(configPath());
|
||||
settings.setOverride("server/port", 1234);
|
||||
|
||||
EXPECT_EQ(settings.value("server/port").toInt(), 1234);
|
||||
// The base class still sees the file value: an override is per-run only.
|
||||
EXPECT_EQ(static_cast<QSettings &>(settings).value("server/port").toInt(), 4747);
|
||||
}
|
||||
|
||||
TEST_F(ServatriceSettingsTest, OverrideAppearsWhenKeyIsAbsentFromTheFile)
|
||||
{
|
||||
writeConfig("[server]\nport=4747\n");
|
||||
SettingsCache settings(configPath());
|
||||
settings.setOverride("server/name", "override-only");
|
||||
|
||||
EXPECT_EQ(settings.value("server/name").toString(), QStringLiteral("override-only"));
|
||||
EXPECT_FALSE(settings.allKeys().contains("server/name"));
|
||||
EXPECT_TRUE(settings.getOverrides().contains("server/name"));
|
||||
}
|
||||
|
||||
TEST_F(ServatriceSettingsTest, RebuildUsesTheOverriddenRegexpList)
|
||||
{
|
||||
writeConfig("[users]\ndisallowedregexp=^bad$\n");
|
||||
SettingsCache settings(configPath());
|
||||
ASSERT_EQ(settings.disallowedRegExp.size(), 1);
|
||||
EXPECT_TRUE(settings.disallowedRegExp.first().match("bad").hasMatch());
|
||||
|
||||
settings.setOverride("users/disallowedregexp", "^worse$");
|
||||
settings.rebuildDisallowedRegExps();
|
||||
|
||||
ASSERT_EQ(settings.disallowedRegExp.size(), 1);
|
||||
EXPECT_TRUE(settings.disallowedRegExp.first().match("worse").hasMatch());
|
||||
EXPECT_FALSE(settings.disallowedRegExp.first().match("bad").hasMatch());
|
||||
}
|
||||
|
||||
TEST_F(ServatriceSettingsTest, EffectiveKeysIncludeOverridesAndStaySorted)
|
||||
{
|
||||
writeConfig("[server]\nport=4747\n");
|
||||
SettingsCache settings(configPath());
|
||||
settings.setOverride("server/name", "override-only");
|
||||
|
||||
const QStringList keys = settings.effectiveKeys();
|
||||
EXPECT_TRUE(keys.contains("server/name"));
|
||||
EXPECT_TRUE(keys.contains("server/port"));
|
||||
|
||||
QStringList sorted = keys;
|
||||
sorted.sort();
|
||||
EXPECT_EQ(keys, sorted);
|
||||
}
|
||||
|
||||
TEST(ServatriceSettingsParsingTest, SecretKeysAreRecognised)
|
||||
{
|
||||
EXPECT_TRUE(SettingsCache::isSecretKey("authentication/password"));
|
||||
EXPECT_TRUE(SettingsCache::isSecretKey("database/password"));
|
||||
EXPECT_TRUE(SettingsCache::isSecretKey("smtp/password"));
|
||||
EXPECT_TRUE(SettingsCache::isSecretKey("security/legacy_backup_key"));
|
||||
EXPECT_TRUE(SettingsCache::isSecretKey("server/apiSecret"));
|
||||
EXPECT_FALSE(SettingsCache::isSecretKey("server/port"));
|
||||
}
|
||||
|
||||
TEST(ServatriceSettingsParsingTest, ParseOverrideAcceptsScalarKeys)
|
||||
{
|
||||
QString key;
|
||||
QVariant value;
|
||||
|
||||
ASSERT_TRUE(SettingsCache::parseOverride("server/port=14747", key, value));
|
||||
EXPECT_EQ(key, QStringLiteral("server/port"));
|
||||
EXPECT_EQ(value.toString(), QStringLiteral("14747"));
|
||||
|
||||
// Only the first '=' separates the key; the rest belongs to the value.
|
||||
ASSERT_TRUE(SettingsCache::parseOverride("server/name=a=b", key, value));
|
||||
EXPECT_EQ(value.toString(), QStringLiteral("a=b"));
|
||||
}
|
||||
|
||||
TEST(ServatriceSettingsParsingTest, ParseOverrideRejectsMalformedEntries)
|
||||
{
|
||||
QString key;
|
||||
QVariant value;
|
||||
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("server/port", key, value));
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("=14747", key, value));
|
||||
EXPECT_FALSE(SettingsCache::parseOverride(" =14747", key, value));
|
||||
}
|
||||
|
||||
TEST(ServatriceSettingsParsingTest, ParseOverrideRejectsBareAndArrayScopedKeys)
|
||||
{
|
||||
QString key;
|
||||
QVariant value;
|
||||
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("name=Kitchen", key, value));
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("rooms/roomlist/1/name=Kitchen", key, value));
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("rooms/roomlist/01/name=Kitchen", key, value));
|
||||
EXPECT_FALSE(SettingsCache::parseOverride("rooms/roomlist/size=2", key, value));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue