SERVER-125549 Refactor knob ID to a strongly-typed struct (#53297)
GitOrigin-RevId: 97f845a9a5a1f16523b5e5bf656fef76877e7da7
This commit is contained in:
parent
5c14ec8028
commit
335a3cc6e7
@ -37,6 +37,8 @@
|
||||
#include "mongo/util/assert_util.h"
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
@ -91,6 +93,24 @@ QueryKnobValue readGlobalValue(StringData paramName) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strong id type to identify query knobs. Defaults to 'kUninitialized'.
|
||||
*/
|
||||
struct QueryKnobId {
|
||||
using value_t = std::uint16_t;
|
||||
constexpr static auto kUninitialized = std::numeric_limits<value_t>::max();
|
||||
|
||||
friend bool operator==(const QueryKnobId& lhs, const QueryKnobId& rhs) {
|
||||
return rhs.value == lhs.value;
|
||||
}
|
||||
|
||||
bool initialized() const {
|
||||
return value != kUninitialized;
|
||||
}
|
||||
|
||||
value_t value = kUninitialized;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type-erased descriptor for a single query knob. Each typed QueryKnob<T> inherits from this and
|
||||
* self-registers into QueryKnobDescriptorSet at static init time. The index field is left as a
|
||||
@ -116,8 +136,7 @@ public:
|
||||
return _readFn(paramName);
|
||||
}
|
||||
|
||||
// TODO SERVER-125549: refactor to use a strongly typed KnobId.
|
||||
size_t index = ~size_t{0}; // Sentinel until QueryKnobRegistry assigns a dense index.
|
||||
QueryKnobId id;
|
||||
StringData paramName;
|
||||
|
||||
private:
|
||||
|
||||
@ -104,11 +104,13 @@ void QueryKnobRegistry::init(QueryKnobRegistry reg) {
|
||||
|
||||
void QueryKnobRegistry::_writeBackDescriptorIndexes() {
|
||||
for (size_t i = 0; i < _entries.size(); ++i) {
|
||||
_entries[i].knob.index = i;
|
||||
auto&& knob = _entries[i].knob;
|
||||
invariant(!knob.id.initialized());
|
||||
knob.id = QueryKnobId(i);
|
||||
}
|
||||
}
|
||||
|
||||
boost::optional<size_t> QueryKnobRegistry::getKnobIdForName(StringData wireName) const {
|
||||
boost::optional<QueryKnobId> QueryKnobRegistry::getKnobIdForName(StringData wireName) const {
|
||||
auto it = _wireNameIndex.find(wireName);
|
||||
if (it == _wireNameIndex.end()) {
|
||||
return boost::none;
|
||||
@ -116,12 +118,12 @@ boost::optional<size_t> QueryKnobRegistry::getKnobIdForName(StringData wireName)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const QueryKnobRegistry::Entry& QueryKnobRegistry::entry(size_t id) const {
|
||||
const QueryKnobRegistry::Entry& QueryKnobRegistry::entry(QueryKnobId id) const {
|
||||
tassert(12317800,
|
||||
str::stream() << "QueryKnobRegistry::entry id " << id << " out of range (size "
|
||||
str::stream() << "QueryKnobRegistry::entry id " << id.value << " out of range (size "
|
||||
<< _entries.size() << ")",
|
||||
id < _entries.size());
|
||||
return _entries[id];
|
||||
id.value < _entries.size());
|
||||
return _entries[id.value];
|
||||
}
|
||||
|
||||
size_t QueryKnobRegistry::knobCount() const {
|
||||
|
||||
@ -76,9 +76,9 @@ public:
|
||||
/**
|
||||
* PQS-settable knobs only; boost::none for non-PQS or unknown name.
|
||||
*/
|
||||
boost::optional<size_t> getKnobIdForName(StringData wireName) const;
|
||||
boost::optional<QueryKnobId> getKnobIdForName(StringData wireName) const;
|
||||
|
||||
const Entry& entry(size_t id) const;
|
||||
const Entry& entry(QueryKnobId id) const;
|
||||
|
||||
size_t knobCount() const;
|
||||
size_t knobsExposedToQuerySettingsCount() const;
|
||||
@ -93,7 +93,7 @@ private:
|
||||
void _writeBackDescriptorIndexes();
|
||||
|
||||
std::vector<Entry> _entries;
|
||||
StringMap<size_t> _wireNameIndex;
|
||||
StringMap<QueryKnobId> _wireNameIndex;
|
||||
size_t _knobsExposedToQuerySettingsCount = 0;
|
||||
bool _initialized = false;
|
||||
};
|
||||
|
||||
@ -57,14 +57,15 @@ namespace {
|
||||
|
||||
// Linear scan for the entry whose `knob` refers to `target`. Returns knobCount()
|
||||
// on miss so callers can assert without risking an out-of-range `entry()` call.
|
||||
size_t findEntryIndex(const QueryKnobBase& target) {
|
||||
QueryKnobId findEntryIndex(const QueryKnobBase& target) {
|
||||
const auto& reg = QueryKnobRegistry::instance();
|
||||
for (size_t i = 0; i < reg.knobCount(); ++i) {
|
||||
if (®.entry(i).knob == &target) {
|
||||
return i;
|
||||
auto id = QueryKnobId(i);
|
||||
if (®.entry(id).knob == &target) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return reg.knobCount();
|
||||
return QueryKnobId(reg.knobCount());
|
||||
}
|
||||
|
||||
// The test IDL registers `synthIntPqs` as a ServerParameter, which is convenient
|
||||
@ -94,7 +95,7 @@ TEST(QueryKnobRegistryTest, NonPqsKnobInvisibleToLookupButCarriesWireName) {
|
||||
ASSERT_FALSE(reg.getKnobIdForName("synthLongNonPqsWire"_sd).has_value());
|
||||
|
||||
auto idx = findEntryIndex(test_synth_knobs::synthLongNonPqsKnob);
|
||||
ASSERT_LT(idx, reg.knobCount());
|
||||
ASSERT_LT(idx.value, reg.knobCount());
|
||||
const auto& e = reg.entry(idx);
|
||||
ASSERT_EQ(e.wireName, "synthLongNonPqsWire"_sd);
|
||||
ASSERT_FALSE(e.pqsSettable);
|
||||
@ -107,7 +108,8 @@ TEST(QueryKnobRegistryTest, PlainServerParameterNotRegistered) {
|
||||
auto* plain = ServerParameterSet::getNodeParameterSet()->getIfExists("synthDoublePlainParam");
|
||||
ASSERT(plain);
|
||||
for (size_t i = 0; i < reg.knobCount(); ++i) {
|
||||
ASSERT_NE(®.entry(i).param, plain);
|
||||
auto id = QueryKnobId(i);
|
||||
ASSERT_NE(®.entry(id).param, plain);
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +125,8 @@ TEST(QueryKnobRegistryTest, MinFcvRoundTrip) {
|
||||
TEST(QueryKnobRegistryTest, DenseIndicesWrittenBackToDescriptors) {
|
||||
const auto& reg = QueryKnobRegistry::instance();
|
||||
for (size_t i = 0; i < reg.knobCount(); ++i) {
|
||||
ASSERT_EQ(reg.entry(i).knob.index, i);
|
||||
auto id = QueryKnobId(i);
|
||||
ASSERT_EQ(reg.entry(id).knob.id, id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +135,8 @@ TEST(QueryKnobRegistryTest, CountsReflectPqsSplitOverSynthSubset) {
|
||||
size_t synthTotal = 0;
|
||||
size_t synthPqs = 0;
|
||||
for (size_t i = 0; i < reg.knobCount(); ++i) {
|
||||
const auto& e = reg.entry(i);
|
||||
auto id = QueryKnobId(i);
|
||||
const auto& e = reg.entry(id);
|
||||
if (e.wireName.starts_with("synth"_sd)) {
|
||||
++synthTotal;
|
||||
if (e.pqsSettable) {
|
||||
@ -162,7 +166,8 @@ DEATH_TEST_REGEX(QueryKnobRegistryDeathTest,
|
||||
EntryGetterOutOfRangeTasserts,
|
||||
"QueryKnobRegistry::entry.*out of range") {
|
||||
const auto& reg = QueryKnobRegistry::instance();
|
||||
reg.entry(reg.knobCount());
|
||||
auto id = QueryKnobId(reg.knobCount());
|
||||
reg.entry(id);
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobRegistryDeathTest,
|
||||
|
||||
@ -72,9 +72,9 @@ public:
|
||||
QueryKnobSnapshot& operator=(QueryKnobSnapshot&&) noexcept = default;
|
||||
|
||||
template <typename T>
|
||||
T get(size_t index) const {
|
||||
tassert(12312300, "QueryKnobSnapshot index out of bounds", index < _values.size());
|
||||
const QueryKnobValue& val = _values[index];
|
||||
T get(QueryKnobId id) const {
|
||||
tassert(12312300, "QueryKnobSnapshot index out of bounds", id.value < _values.size());
|
||||
const QueryKnobValue& val = _values[id.value];
|
||||
if constexpr (std::is_enum_v<T>) {
|
||||
return static_cast<T>(std::get<int>(val));
|
||||
} else {
|
||||
@ -82,9 +82,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
KnobSource getSource(size_t index) const {
|
||||
tassert(12312301, "QueryKnobSnapshot index out of bounds", index < _sources.size());
|
||||
return _sources[index];
|
||||
KnobSource getSource(QueryKnobId id) const {
|
||||
tassert(12312301, "QueryKnobSnapshot index out of bounds", id.value < _sources.size());
|
||||
return _sources[id.value];
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
@ -115,13 +115,14 @@ public:
|
||||
QueryKnobSnapshotBuilder(const QueryKnobSnapshotBuilder&) = delete;
|
||||
QueryKnobSnapshotBuilder& operator=(const QueryKnobSnapshotBuilder&) = delete;
|
||||
|
||||
QueryKnobSnapshotBuilder& set(size_t index, QueryKnobValue value, KnobSource source) {
|
||||
tassert(12312302, "QueryKnobSnapshotBuilder index out of bounds", index < _values.size());
|
||||
QueryKnobSnapshotBuilder& set(QueryKnobId id, QueryKnobValue value, KnobSource source) {
|
||||
tassert(
|
||||
12312302, "QueryKnobSnapshotBuilder index out of bounds", id.value < _values.size());
|
||||
tassert(12312303,
|
||||
"QueryKnobSnapshotBuilder::set() value must not be DeleteQueryKnobOverride",
|
||||
!std::holds_alternative<DeleteQueryKnobOverride>(value));
|
||||
_values[index] = std::move(value);
|
||||
_sources[index] = source;
|
||||
_values[id.value] = std::move(value);
|
||||
_sources[id.value] = source;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ namespace {
|
||||
|
||||
TEST(QueryKnobSnapshotTest, SizeMatchesConstructorArgument) {
|
||||
auto builder = QueryKnobSnapshotBuilder{5};
|
||||
for (int i = 0; i < 5; i++) {
|
||||
builder.set(i, QueryKnobValue{i}, KnobSource::kDefault);
|
||||
for (QueryKnobId::value_t i = 0; i < 5; i++) {
|
||||
builder.set(QueryKnobId{i}, QueryKnobValue{static_cast<int>(i)}, KnobSource::kDefault);
|
||||
}
|
||||
ASSERT_EQ(std::move(builder).build().size(), 5u);
|
||||
}
|
||||
@ -56,158 +56,166 @@ TEST(QueryKnobSnapshotTest, RoundTripAllQueryKnobValueTypes) {
|
||||
constexpr auto kEnumVal = QueryFrameworkControlEnum::kTrySbeRestricted;
|
||||
auto snap =
|
||||
std::move(QueryKnobSnapshotBuilder{5}
|
||||
.set(0, QueryKnobValue{42}, KnobSource::kDefault)
|
||||
.set(1, QueryKnobValue{123456789LL}, KnobSource::kDefault)
|
||||
.set(2, QueryKnobValue{2.718}, KnobSource::kDefault)
|
||||
.set(3, QueryKnobValue{true}, KnobSource::kDefault)
|
||||
.set(4, QueryKnobValue{static_cast<int>(kEnumVal)}, KnobSource::kDefault))
|
||||
.set(QueryKnobId{0}, QueryKnobValue{42}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{1}, QueryKnobValue{123456789LL}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{2}, QueryKnobValue{2.718}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{3}, QueryKnobValue{true}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{4},
|
||||
QueryKnobValue{static_cast<int>(kEnumVal)},
|
||||
KnobSource::kDefault))
|
||||
.build();
|
||||
|
||||
ASSERT_EQ(snap.get<int>(0), 42);
|
||||
ASSERT_EQ(snap.get<long long>(1), 123456789LL);
|
||||
ASSERT_APPROX_EQUAL(snap.get<double>(2), 2.718, 1e-9);
|
||||
ASSERT_EQ(snap.get<bool>(3), true);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(4), kEnumVal);
|
||||
ASSERT_EQ(snap.get<int>(QueryKnobId{0}), 42);
|
||||
ASSERT_EQ(snap.get<long long>(QueryKnobId{1}), 123456789LL);
|
||||
ASSERT_APPROX_EQUAL(snap.get<double>(QueryKnobId{2}), 2.718, 1e-9);
|
||||
ASSERT_EQ(snap.get<bool>(QueryKnobId{3}), true);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(QueryKnobId{4}), kEnumVal);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, RoundTripInt) {
|
||||
auto snap =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{42}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snap.get<int>(0), 42);
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{42}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snap.get<int>(QueryKnobId{0}), 42);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, RoundTripLongLong) {
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
0, QueryKnobValue{123456789LL}, KnobSource::kDefault))
|
||||
QueryKnobId{0}, QueryKnobValue{123456789LL}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snap.get<long long>(0), 123456789LL);
|
||||
ASSERT_EQ(snap.get<long long>(QueryKnobId{0}), 123456789LL);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, RoundTripDouble) {
|
||||
auto snap =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{2.718}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_APPROX_EQUAL(snap.get<double>(0), 2.718, 1e-9);
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{2.718}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_APPROX_EQUAL(snap.get<double>(QueryKnobId{0}), 2.718, 1e-9);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, RoundTripBool) {
|
||||
auto snapFalse =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{false}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snapFalse.get<bool>(0), false);
|
||||
auto snapFalse = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{false}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snapFalse.get<bool>(QueryKnobId{0}), false);
|
||||
|
||||
auto snapTrue =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{true}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snapTrue.get<bool>(0), true);
|
||||
auto snapTrue = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{true}, KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snapTrue.get<bool>(QueryKnobId{0}), true);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, EnumCastRoundTrip) {
|
||||
auto enumVal = QueryFrameworkControlEnum::kForceClassicEngine;
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
0, QueryKnobValue{static_cast<int>(enumVal)}, KnobSource::kDefault))
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(QueryKnobId{0},
|
||||
QueryKnobValue{static_cast<int>(enumVal)},
|
||||
KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(0), enumVal);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(QueryKnobId{0}), enumVal);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, EnumCastAllValues) {
|
||||
auto snap =
|
||||
std::move(
|
||||
QueryKnobSnapshotBuilder{3}
|
||||
.set(0,
|
||||
.set(QueryKnobId{0},
|
||||
QueryKnobValue{static_cast<int>(QueryFrameworkControlEnum::kTrySbeEngine)},
|
||||
KnobSource::kDefault)
|
||||
.set(1,
|
||||
.set(QueryKnobId{1},
|
||||
QueryKnobValue{static_cast<int>(QueryFrameworkControlEnum::kTrySbeRestricted)},
|
||||
KnobSource::kDefault)
|
||||
.set(2,
|
||||
.set(QueryKnobId{2},
|
||||
QueryKnobValue{
|
||||
static_cast<int>(QueryFrameworkControlEnum::kForceClassicEngine)},
|
||||
KnobSource::kDefault))
|
||||
.build();
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(0), QueryFrameworkControlEnum::kTrySbeEngine);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(1), QueryFrameworkControlEnum::kTrySbeRestricted);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(2),
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(QueryKnobId{0}),
|
||||
QueryFrameworkControlEnum::kTrySbeEngine);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(QueryKnobId{1}),
|
||||
QueryFrameworkControlEnum::kTrySbeRestricted);
|
||||
ASSERT_EQ(snap.get<QueryFrameworkControlEnum>(QueryKnobId{2}),
|
||||
QueryFrameworkControlEnum::kForceClassicEngine);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, SourceTrackingSetParameter) {
|
||||
auto snap =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{7}, KnobSource::kSetParameter))
|
||||
.build();
|
||||
ASSERT_EQ(snap.getSource(0), KnobSource::kSetParameter);
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{7}, KnobSource::kSetParameter))
|
||||
.build();
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{0}), KnobSource::kSetParameter);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, SourceTrackingQuerySettings) {
|
||||
auto snap =
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{7}, KnobSource::kQuerySettings))
|
||||
.build();
|
||||
ASSERT_EQ(snap.getSource(0), KnobSource::kQuerySettings);
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, QueryKnobValue{7}, KnobSource::kQuerySettings))
|
||||
.build();
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{0}), KnobSource::kQuerySettings);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, MultipleSlotSourcesAreIndependent) {
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{3}
|
||||
.set(0, QueryKnobValue{1}, KnobSource::kDefault)
|
||||
.set(1, QueryKnobValue{2}, KnobSource::kSetParameter)
|
||||
.set(2, QueryKnobValue{3}, KnobSource::kQuerySettings))
|
||||
.set(QueryKnobId{0}, QueryKnobValue{1}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{1}, QueryKnobValue{2}, KnobSource::kSetParameter)
|
||||
.set(QueryKnobId{2}, QueryKnobValue{3}, KnobSource::kQuerySettings))
|
||||
.build();
|
||||
ASSERT_EQ(snap.getSource(0), KnobSource::kDefault);
|
||||
ASSERT_EQ(snap.getSource(1), KnobSource::kSetParameter);
|
||||
ASSERT_EQ(snap.getSource(2), KnobSource::kQuerySettings);
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{0}), KnobSource::kDefault);
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{1}), KnobSource::kSetParameter);
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{2}), KnobSource::kQuerySettings);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, CopyIsIndependent) {
|
||||
auto original = std::move(QueryKnobSnapshotBuilder{2}
|
||||
.set(0, QueryKnobValue{10}, KnobSource::kDefault)
|
||||
.set(1, QueryKnobValue{20LL}, KnobSource::kSetParameter))
|
||||
.build();
|
||||
auto original =
|
||||
std::move(QueryKnobSnapshotBuilder{2}
|
||||
.set(QueryKnobId{0}, QueryKnobValue{10}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{1}, QueryKnobValue{20LL}, KnobSource::kSetParameter))
|
||||
.build();
|
||||
|
||||
// Copy-construct from original.
|
||||
QueryKnobSnapshot copy = original;
|
||||
ASSERT_EQ(copy.get<int>(0), 10);
|
||||
ASSERT_EQ(copy.get<long long>(1), 20LL);
|
||||
ASSERT_EQ(copy.getSource(0), KnobSource::kDefault);
|
||||
ASSERT_EQ(copy.getSource(1), KnobSource::kSetParameter);
|
||||
ASSERT_EQ(copy.get<int>(QueryKnobId{0}), 10);
|
||||
ASSERT_EQ(copy.get<long long>(QueryKnobId{1}), 20LL);
|
||||
ASSERT_EQ(copy.getSource(QueryKnobId{0}), KnobSource::kDefault);
|
||||
ASSERT_EQ(copy.getSource(QueryKnobId{1}), KnobSource::kSetParameter);
|
||||
|
||||
// Assigning a new snapshot to copy does not affect original.
|
||||
copy = std::move(QueryKnobSnapshotBuilder{2}
|
||||
.set(0, QueryKnobValue{99}, KnobSource::kQuerySettings)
|
||||
.set(1, QueryKnobValue{999LL}, KnobSource::kQuerySettings))
|
||||
.set(QueryKnobId{0}, QueryKnobValue{99}, KnobSource::kQuerySettings)
|
||||
.set(QueryKnobId{1}, QueryKnobValue{999LL}, KnobSource::kQuerySettings))
|
||||
.build();
|
||||
|
||||
ASSERT_EQ(original.get<int>(0), 10);
|
||||
ASSERT_EQ(original.get<long long>(1), 20LL);
|
||||
ASSERT_EQ(original.getSource(0), KnobSource::kDefault);
|
||||
ASSERT_EQ(original.getSource(1), KnobSource::kSetParameter);
|
||||
ASSERT_EQ(original.get<int>(QueryKnobId{0}), 10);
|
||||
ASSERT_EQ(original.get<long long>(QueryKnobId{1}), 20LL);
|
||||
ASSERT_EQ(original.getSource(QueryKnobId{0}), KnobSource::kDefault);
|
||||
ASSERT_EQ(original.getSource(QueryKnobId{1}), KnobSource::kSetParameter);
|
||||
}
|
||||
|
||||
TEST(QueryKnobSnapshotTest, LastWriteWins) {
|
||||
auto snap = std::move(QueryKnobSnapshotBuilder{1}
|
||||
.set(0, QueryKnobValue{5}, KnobSource::kDefault)
|
||||
.set(0, QueryKnobValue{42}, KnobSource::kSetParameter))
|
||||
.set(QueryKnobId{0}, QueryKnobValue{5}, KnobSource::kDefault)
|
||||
.set(QueryKnobId{0}, QueryKnobValue{42}, KnobSource::kSetParameter))
|
||||
.build();
|
||||
|
||||
ASSERT_EQ(snap.get<int>(0), 42);
|
||||
ASSERT_EQ(snap.getSource(0), KnobSource::kSetParameter);
|
||||
ASSERT_EQ(snap.get<int>(QueryKnobId{0}), 42);
|
||||
ASSERT_EQ(snap.getSource(QueryKnobId{0}), KnobSource::kSetParameter);
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobSnapshotDeathTest, GetOutOfBounds, "12312300") {
|
||||
QueryKnobSnapshotBuilder{0}.build().get<int>(2);
|
||||
QueryKnobSnapshotBuilder{0}.build().get<int>(QueryKnobId{2});
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobSnapshotDeathTest, GetSourceOutOfBounds, "12312301") {
|
||||
std::move(QueryKnobSnapshotBuilder{1}.set(0, QueryKnobValue{0}, KnobSource::kDefault))
|
||||
std::move(
|
||||
QueryKnobSnapshotBuilder{1}.set(QueryKnobId{0}, QueryKnobValue{0}, KnobSource::kDefault))
|
||||
.build()
|
||||
.getSource(2);
|
||||
.getSource(QueryKnobId{2});
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobSnapshotDeathTest, SetOutOfBounds, "12312302") {
|
||||
QueryKnobSnapshotBuilder{2}.set(5, QueryKnobValue{1}, KnobSource::kDefault);
|
||||
QueryKnobSnapshotBuilder{2}.set(QueryKnobId{5}, QueryKnobValue{1}, KnobSource::kDefault);
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobSnapshotDeathTest, SetDeleteQueryKnobOverrideValue, "12312303") {
|
||||
QueryKnobSnapshotBuilder{1}.set(0, DeleteQueryKnobOverride(), KnobSource::kDefault);
|
||||
QueryKnobSnapshotBuilder{1}.set(
|
||||
QueryKnobId{0}, DeleteQueryKnobOverride(), KnobSource::kDefault);
|
||||
}
|
||||
|
||||
DEATH_TEST_REGEX(QueryKnobSnapshotDeathTest,
|
||||
|
||||
@ -81,11 +81,11 @@ TEST(QueryKnobTest, SyntheticKnobsSelfRegister) {
|
||||
}
|
||||
|
||||
TEST(QueryKnobTest, SentinelIndex) {
|
||||
ASSERT_EQ(test_knobs::testIntKnob.index, ~size_t{0});
|
||||
ASSERT_EQ(test_knobs::testDoubleKnob.index, ~size_t{0});
|
||||
ASSERT_EQ(test_knobs::testBoolKnob.index, ~size_t{0});
|
||||
ASSERT_EQ(test_knobs::testLLKnob.index, ~size_t{0});
|
||||
ASSERT_EQ(test_knobs::testEnumKnob.index, ~size_t{0});
|
||||
ASSERT_FALSE(test_knobs::testIntKnob.id.initialized());
|
||||
ASSERT_FALSE(test_knobs::testDoubleKnob.id.initialized());
|
||||
ASSERT_FALSE(test_knobs::testBoolKnob.id.initialized());
|
||||
ASSERT_FALSE(test_knobs::testLLKnob.id.initialized());
|
||||
ASSERT_FALSE(test_knobs::testEnumKnob.id.initialized());
|
||||
}
|
||||
|
||||
TEST(QueryKnobTest, ReadGlobalInt) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user