mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +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_size",
|
||||
"../../api/units:time_delta",
|
||||
"../../rtc_base:checks",
|
||||
"../../system_wrappers:field_trial_api",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -28,7 +29,10 @@ int FindOrEnd(std::string str, size_t start, char delimiter) {
|
|||
|
||||
FieldTrialParameterInterface::FieldTrialParameterInterface(std::string key)
|
||||
: key_(key) {}
|
||||
FieldTrialParameterInterface::~FieldTrialParameterInterface() = default;
|
||||
FieldTrialParameterInterface::~FieldTrialParameterInterface() {
|
||||
RTC_DCHECK(used_) << "Field trial parameter with key: '" << key_
|
||||
<< "' never used.";
|
||||
}
|
||||
std::string FieldTrialParameterInterface::Key() const {
|
||||
return key_;
|
||||
}
|
||||
|
@ -38,6 +42,7 @@ void ParseFieldTrial(
|
|||
std::string trial_string) {
|
||||
std::map<std::string, FieldTrialParameterInterface*> field_map;
|
||||
for (FieldTrialParameterInterface* field : fields) {
|
||||
field->MarkAsUsed();
|
||||
field_map[field->Key()] = field;
|
||||
}
|
||||
size_t i = 0;
|
||||
|
@ -108,6 +113,10 @@ bool FieldTrialFlag::Get() const {
|
|||
return value_;
|
||||
}
|
||||
|
||||
webrtc::FieldTrialFlag::operator bool() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
|
||||
// Only set the flag if there is no argument provided.
|
||||
if (str_value) {
|
||||
|
|
|
@ -41,11 +41,13 @@ class FieldTrialParameterInterface {
|
|||
friend void ParseFieldTrial(
|
||||
std::initializer_list<FieldTrialParameterInterface*> fields,
|
||||
std::string raw_string);
|
||||
void MarkAsUsed() { used_ = true; }
|
||||
virtual bool Parse(absl::optional<std::string> str_value) = 0;
|
||||
std::string Key() const;
|
||||
|
||||
private:
|
||||
const std::string key_;
|
||||
bool used_ = false;
|
||||
};
|
||||
|
||||
// ParseFieldTrial function parses the given string and fills the given fields
|
||||
|
@ -68,6 +70,7 @@ class FieldTrialParameter : public FieldTrialParameterInterface {
|
|||
: FieldTrialParameterInterface(key), value_(default_value) {}
|
||||
T Get() const { return value_; }
|
||||
operator T() const { return Get(); }
|
||||
const T* operator->() const { return &value_; }
|
||||
|
||||
protected:
|
||||
bool Parse(absl::optional<std::string> str_value) override {
|
||||
|
@ -135,7 +138,11 @@ class FieldTrialOptional : public FieldTrialParameterInterface {
|
|||
: FieldTrialParameterInterface(key) {}
|
||||
FieldTrialOptional(std::string key, absl::optional<T> 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:
|
||||
bool Parse(absl::optional<std::string> str_value) override {
|
||||
|
@ -162,6 +169,7 @@ class FieldTrialFlag : public FieldTrialParameterInterface {
|
|||
explicit FieldTrialFlag(std::string key);
|
||||
FieldTrialFlag(std::string key, bool default_value);
|
||||
bool Get() const;
|
||||
operator bool() const;
|
||||
|
||||
protected:
|
||||
bool Parse(absl::optional<std::string> str_value) override;
|
||||
|
|
|
@ -93,20 +93,20 @@ TEST(FieldTrialParserTest, IgnoresInvalid) {
|
|||
TEST(FieldTrialParserTest, ParsesOptionalParameters) {
|
||||
FieldTrialOptional<int> max_count("c", absl::nullopt);
|
||||
ParseFieldTrial({&max_count}, "");
|
||||
EXPECT_FALSE(max_count.Get().has_value());
|
||||
EXPECT_FALSE(max_count.GetOptional().has_value());
|
||||
ParseFieldTrial({&max_count}, "c:10");
|
||||
EXPECT_EQ(max_count.Get().value(), 10);
|
||||
EXPECT_EQ(max_count.GetOptional().value(), 10);
|
||||
ParseFieldTrial({&max_count}, "c");
|
||||
EXPECT_FALSE(max_count.Get().has_value());
|
||||
EXPECT_FALSE(max_count.GetOptional().has_value());
|
||||
ParseFieldTrial({&max_count}, "c:20");
|
||||
EXPECT_EQ(max_count.Get().value(), 20);
|
||||
EXPECT_EQ(max_count.GetOptional().value(), 20);
|
||||
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"));
|
||||
ParseFieldTrial({&optional_string}, "s:");
|
||||
EXPECT_EQ(optional_string.Get().value(), "");
|
||||
EXPECT_EQ(optional_string.GetOptional().value(), "");
|
||||
ParseFieldTrial({&optional_string}, "s");
|
||||
EXPECT_FALSE(optional_string.Get().has_value());
|
||||
EXPECT_FALSE(optional_string.GetOptional().has_value());
|
||||
}
|
||||
TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
|
||||
FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
|
||||
|
|
|
@ -32,19 +32,19 @@ struct DummyExperiment {
|
|||
TEST(FieldTrialParserUnitsTest, FallsBackToDefaults) {
|
||||
DummyExperiment exp("");
|
||||
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));
|
||||
}
|
||||
TEST(FieldTrialParserUnitsTest, ParsesUnitParameters) {
|
||||
DummyExperiment exp("t:300kbps,b:5bytes,p:300ms");
|
||||
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));
|
||||
}
|
||||
TEST(FieldTrialParserUnitsTest, ParsesDefaultUnitParameters) {
|
||||
DummyExperiment exp("t:300,b:5,p: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));
|
||||
}
|
||||
TEST(FieldTrialParserUnitsTest, ParsesInfinityParameter) {
|
||||
|
@ -55,7 +55,7 @@ TEST(FieldTrialParserUnitsTest, ParsesInfinityParameter) {
|
|||
TEST(FieldTrialParserUnitsTest, ParsesOtherUnitParameters) {
|
||||
DummyExperiment exp("t:300bps,p:0.3 seconds,b:8 bytes");
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue