mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00
Adds check for unused field trial parameters.
This adds a dcheck to detect if a FieldTrialParameter has been created but not used in parsing a field trial. This is an easy mistake to make and cause extra work debugging why nothing happens. Also improving the ergonomics of using the parameter and optional classes. Making it easier to use them as drop in replacements for their underlying classes. In particular, the optional parameter class implements and interface more similar to the optional class. Bug: webrtc:9510 Change-Id: I5a12dd66396fa4cac9c9cf517172ae2f06984060 Reviewed-on: https://webrtc-review.googlesource.com/96761 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24527}
This commit is contained in:
parent
88e1848fd5
commit
fea4637cfe
5 changed files with 31 additions and 13 deletions
|
@ -32,6 +32,7 @@ rtc_static_library("field_trial_parser") {
|
||||||
"../../api/units:data_rate",
|
"../../api/units:data_rate",
|
||||||
"../../api/units:data_size",
|
"../../api/units:data_size",
|
||||||
"../../api/units:time_delta",
|
"../../api/units:time_delta",
|
||||||
|
"../../rtc_base:checks",
|
||||||
"../../system_wrappers:field_trial_api",
|
"../../system_wrappers:field_trial_api",
|
||||||
"//third_party/abseil-cpp/absl/types:optional",
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
]
|
]
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
@ -28,7 +29,10 @@ int FindOrEnd(std::string str, size_t start, char delimiter) {
|
||||||
|
|
||||||
FieldTrialParameterInterface::FieldTrialParameterInterface(std::string key)
|
FieldTrialParameterInterface::FieldTrialParameterInterface(std::string key)
|
||||||
: key_(key) {}
|
: key_(key) {}
|
||||||
FieldTrialParameterInterface::~FieldTrialParameterInterface() = default;
|
FieldTrialParameterInterface::~FieldTrialParameterInterface() {
|
||||||
|
RTC_DCHECK(used_) << "Field trial parameter with key: '" << key_
|
||||||
|
<< "' never used.";
|
||||||
|
}
|
||||||
std::string FieldTrialParameterInterface::Key() const {
|
std::string FieldTrialParameterInterface::Key() const {
|
||||||
return key_;
|
return key_;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +42,7 @@ void ParseFieldTrial(
|
||||||
std::string trial_string) {
|
std::string trial_string) {
|
||||||
std::map<std::string, FieldTrialParameterInterface*> field_map;
|
std::map<std::string, FieldTrialParameterInterface*> field_map;
|
||||||
for (FieldTrialParameterInterface* field : fields) {
|
for (FieldTrialParameterInterface* field : fields) {
|
||||||
|
field->MarkAsUsed();
|
||||||
field_map[field->Key()] = field;
|
field_map[field->Key()] = field;
|
||||||
}
|
}
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -108,6 +113,10 @@ bool FieldTrialFlag::Get() const {
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
webrtc::FieldTrialFlag::operator bool() const {
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
|
bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
|
||||||
// Only set the flag if there is no argument provided.
|
// Only set the flag if there is no argument provided.
|
||||||
if (str_value) {
|
if (str_value) {
|
||||||
|
|
|
@ -41,11 +41,13 @@ class FieldTrialParameterInterface {
|
||||||
friend void ParseFieldTrial(
|
friend void ParseFieldTrial(
|
||||||
std::initializer_list<FieldTrialParameterInterface*> fields,
|
std::initializer_list<FieldTrialParameterInterface*> fields,
|
||||||
std::string raw_string);
|
std::string raw_string);
|
||||||
|
void MarkAsUsed() { used_ = true; }
|
||||||
virtual bool Parse(absl::optional<std::string> str_value) = 0;
|
virtual bool Parse(absl::optional<std::string> str_value) = 0;
|
||||||
std::string Key() const;
|
std::string Key() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string key_;
|
const std::string key_;
|
||||||
|
bool used_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ParseFieldTrial function parses the given string and fills the given fields
|
// ParseFieldTrial function parses the given string and fills the given fields
|
||||||
|
@ -68,6 +70,7 @@ class FieldTrialParameter : public FieldTrialParameterInterface {
|
||||||
: FieldTrialParameterInterface(key), value_(default_value) {}
|
: FieldTrialParameterInterface(key), value_(default_value) {}
|
||||||
T Get() const { return value_; }
|
T Get() const { return value_; }
|
||||||
operator T() const { return Get(); }
|
operator T() const { return Get(); }
|
||||||
|
const T* operator->() const { return &value_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Parse(absl::optional<std::string> str_value) override {
|
bool Parse(absl::optional<std::string> str_value) override {
|
||||||
|
@ -135,7 +138,11 @@ class FieldTrialOptional : public FieldTrialParameterInterface {
|
||||||
: FieldTrialParameterInterface(key) {}
|
: FieldTrialParameterInterface(key) {}
|
||||||
FieldTrialOptional(std::string key, absl::optional<T> default_value)
|
FieldTrialOptional(std::string key, absl::optional<T> default_value)
|
||||||
: FieldTrialParameterInterface(key), value_(default_value) {}
|
: FieldTrialParameterInterface(key), value_(default_value) {}
|
||||||
absl::optional<T> Get() const { return value_; }
|
absl::optional<T> GetOptional() const { return value_; }
|
||||||
|
const T& Value() const { return value_.value(); }
|
||||||
|
const T& operator*() const { return value_.value(); }
|
||||||
|
const T* operator->() const { return &value_.value(); }
|
||||||
|
operator bool() const { return value_.has_value(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Parse(absl::optional<std::string> str_value) override {
|
bool Parse(absl::optional<std::string> str_value) override {
|
||||||
|
@ -162,6 +169,7 @@ class FieldTrialFlag : public FieldTrialParameterInterface {
|
||||||
explicit FieldTrialFlag(std::string key);
|
explicit FieldTrialFlag(std::string key);
|
||||||
FieldTrialFlag(std::string key, bool default_value);
|
FieldTrialFlag(std::string key, bool default_value);
|
||||||
bool Get() const;
|
bool Get() const;
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Parse(absl::optional<std::string> str_value) override;
|
bool Parse(absl::optional<std::string> str_value) override;
|
||||||
|
|
|
@ -93,20 +93,20 @@ TEST(FieldTrialParserTest, IgnoresInvalid) {
|
||||||
TEST(FieldTrialParserTest, ParsesOptionalParameters) {
|
TEST(FieldTrialParserTest, ParsesOptionalParameters) {
|
||||||
FieldTrialOptional<int> max_count("c", absl::nullopt);
|
FieldTrialOptional<int> max_count("c", absl::nullopt);
|
||||||
ParseFieldTrial({&max_count}, "");
|
ParseFieldTrial({&max_count}, "");
|
||||||
EXPECT_FALSE(max_count.Get().has_value());
|
EXPECT_FALSE(max_count.GetOptional().has_value());
|
||||||
ParseFieldTrial({&max_count}, "c:10");
|
ParseFieldTrial({&max_count}, "c:10");
|
||||||
EXPECT_EQ(max_count.Get().value(), 10);
|
EXPECT_EQ(max_count.GetOptional().value(), 10);
|
||||||
ParseFieldTrial({&max_count}, "c");
|
ParseFieldTrial({&max_count}, "c");
|
||||||
EXPECT_FALSE(max_count.Get().has_value());
|
EXPECT_FALSE(max_count.GetOptional().has_value());
|
||||||
ParseFieldTrial({&max_count}, "c:20");
|
ParseFieldTrial({&max_count}, "c:20");
|
||||||
EXPECT_EQ(max_count.Get().value(), 20);
|
EXPECT_EQ(max_count.GetOptional().value(), 20);
|
||||||
ParseFieldTrial({&max_count}, "c:");
|
ParseFieldTrial({&max_count}, "c:");
|
||||||
EXPECT_EQ(max_count.Get().value(), 20);
|
EXPECT_EQ(max_count.GetOptional().value(), 20);
|
||||||
FieldTrialOptional<std::string> optional_string("s", std::string("ab"));
|
FieldTrialOptional<std::string> optional_string("s", std::string("ab"));
|
||||||
ParseFieldTrial({&optional_string}, "s:");
|
ParseFieldTrial({&optional_string}, "s:");
|
||||||
EXPECT_EQ(optional_string.Get().value(), "");
|
EXPECT_EQ(optional_string.GetOptional().value(), "");
|
||||||
ParseFieldTrial({&optional_string}, "s");
|
ParseFieldTrial({&optional_string}, "s");
|
||||||
EXPECT_FALSE(optional_string.Get().has_value());
|
EXPECT_FALSE(optional_string.GetOptional().has_value());
|
||||||
}
|
}
|
||||||
TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
|
TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
|
||||||
FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
|
FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
|
||||||
|
|
|
@ -32,19 +32,19 @@ struct DummyExperiment {
|
||||||
TEST(FieldTrialParserUnitsTest, FallsBackToDefaults) {
|
TEST(FieldTrialParserUnitsTest, FallsBackToDefaults) {
|
||||||
DummyExperiment exp("");
|
DummyExperiment exp("");
|
||||||
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(100));
|
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(100));
|
||||||
EXPECT_FALSE(exp.max_buffer.Get().has_value());
|
EXPECT_FALSE(exp.max_buffer.GetOptional().has_value());
|
||||||
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(100));
|
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(100));
|
||||||
}
|
}
|
||||||
TEST(FieldTrialParserUnitsTest, ParsesUnitParameters) {
|
TEST(FieldTrialParserUnitsTest, ParsesUnitParameters) {
|
||||||
DummyExperiment exp("t:300kbps,b:5bytes,p:300ms");
|
DummyExperiment exp("t:300kbps,b:5bytes,p:300ms");
|
||||||
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(300));
|
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(300));
|
||||||
EXPECT_EQ(*exp.max_buffer.Get(), DataSize::bytes(5));
|
EXPECT_EQ(*exp.max_buffer.GetOptional(), DataSize::bytes(5));
|
||||||
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
||||||
}
|
}
|
||||||
TEST(FieldTrialParserUnitsTest, ParsesDefaultUnitParameters) {
|
TEST(FieldTrialParserUnitsTest, ParsesDefaultUnitParameters) {
|
||||||
DummyExperiment exp("t:300,b:5,p:300");
|
DummyExperiment exp("t:300,b:5,p:300");
|
||||||
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(300));
|
EXPECT_EQ(exp.target_rate.Get(), DataRate::kbps(300));
|
||||||
EXPECT_EQ(*exp.max_buffer.Get(), DataSize::bytes(5));
|
EXPECT_EQ(*exp.max_buffer.GetOptional(), DataSize::bytes(5));
|
||||||
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
||||||
}
|
}
|
||||||
TEST(FieldTrialParserUnitsTest, ParsesInfinityParameter) {
|
TEST(FieldTrialParserUnitsTest, ParsesInfinityParameter) {
|
||||||
|
@ -55,7 +55,7 @@ TEST(FieldTrialParserUnitsTest, ParsesInfinityParameter) {
|
||||||
TEST(FieldTrialParserUnitsTest, ParsesOtherUnitParameters) {
|
TEST(FieldTrialParserUnitsTest, ParsesOtherUnitParameters) {
|
||||||
DummyExperiment exp("t:300bps,p:0.3 seconds,b:8 bytes");
|
DummyExperiment exp("t:300bps,p:0.3 seconds,b:8 bytes");
|
||||||
EXPECT_EQ(exp.target_rate.Get(), DataRate::bps(300));
|
EXPECT_EQ(exp.target_rate.Get(), DataRate::bps(300));
|
||||||
EXPECT_EQ(*exp.max_buffer.Get(), DataSize::bytes(8));
|
EXPECT_EQ(*exp.max_buffer.GetOptional(), DataSize::bytes(8));
|
||||||
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue