From b22f077a60fb7f57e53a6650f0b7a9c53eb47450 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Mon, 19 Nov 2018 17:44:33 +0100 Subject: [PATCH] Adds FieldTrialConstrained class. Bug: webrtc:9346 Change-Id: I8ac232f012cae1d1bd9d862a572aba82bb8ca031 Reviewed-on: https://webrtc-review.googlesource.com/c/111255 Commit-Queue: Sebastian Jansson Reviewed-by: Christoffer Rodbro Cr-Commit-Position: refs/heads/master@{#25700} --- rtc_base/experiments/field_trial_parser.cc | 3 ++ rtc_base/experiments/field_trial_parser.h | 40 +++++++++++++++++++ .../field_trial_parser_unittest.cc | 13 ++++++ rtc_base/experiments/field_trial_units.cc | 4 ++ rtc_base/experiments/field_trial_units.h | 4 ++ .../experiments/field_trial_units_unittest.cc | 20 ++++++++++ 6 files changed, 84 insertions(+) diff --git a/rtc_base/experiments/field_trial_parser.cc b/rtc_base/experiments/field_trial_parser.cc index a2d7f97bde..936487cb01 100644 --- a/rtc_base/experiments/field_trial_parser.cc +++ b/rtc_base/experiments/field_trial_parser.cc @@ -169,6 +169,9 @@ template class FieldTrialParameter; template class FieldTrialParameter; template class FieldTrialParameter; +template class FieldTrialConstrained; +template class FieldTrialConstrained; + template class FieldTrialOptional; template class FieldTrialOptional; template class FieldTrialOptional; diff --git a/rtc_base/experiments/field_trial_parser.h b/rtc_base/experiments/field_trial_parser.h index 22a8889717..8bdd9b5d8e 100644 --- a/rtc_base/experiments/field_trial_parser.h +++ b/rtc_base/experiments/field_trial_parser.h @@ -92,6 +92,43 @@ class FieldTrialParameter : public FieldTrialParameterInterface { T value_; }; +// This class uses the ParseTypedParameter function to implement a parameter +// implementation with an enforced default value and a range constraint. Values +// outside the configured range will be ignored. +template +class FieldTrialConstrained : public FieldTrialParameterInterface { + public: + FieldTrialConstrained(std::string key, + T default_value, + absl::optional lower_limit, + absl::optional upper_limit) + : FieldTrialParameterInterface(key), + value_(default_value), + lower_limit_(lower_limit), + upper_limit_(upper_limit) {} + T Get() const { return value_; } + operator T() const { return Get(); } + const T* operator->() const { return &value_; } + + protected: + bool Parse(absl::optional str_value) override { + if (str_value) { + absl::optional value = ParseTypedParameter(*str_value); + if (value && (!lower_limit_ || *value >= *lower_limit_) && + (!upper_limit_ || *value <= *upper_limit_)) { + value_ = *value; + return true; + } + } + return false; + } + + private: + T value_; + absl::optional lower_limit_; + absl::optional upper_limit_; +}; + class AbstractFieldTrialEnum : public FieldTrialParameterInterface { public: AbstractFieldTrialEnum(std::string key, @@ -191,6 +228,9 @@ extern template class FieldTrialParameter; // Using the given value as is. extern template class FieldTrialParameter; +extern template class FieldTrialConstrained; +extern template class FieldTrialConstrained; + extern template class FieldTrialOptional; extern template class FieldTrialOptional; extern template class FieldTrialOptional; diff --git a/rtc_base/experiments/field_trial_parser_unittest.cc b/rtc_base/experiments/field_trial_parser_unittest.cc index de977ec8ba..0d067f5a49 100644 --- a/rtc_base/experiments/field_trial_parser_unittest.cc +++ b/rtc_base/experiments/field_trial_parser_unittest.cc @@ -99,6 +99,19 @@ TEST(FieldTrialParserTest, IgnoresInvalid) { EXPECT_EQ(exp.ping.Get(), false); EXPECT_EQ(exp.hash.Get(), "a80"); } +TEST(FieldTrialParserTest, IgnoresOutOfRange) { + FieldTrialConstrained low("low", 10, absl::nullopt, 100); + FieldTrialConstrained high("high", 10, 5, absl::nullopt); + ParseFieldTrial({&low, &high}, "low:1000,high:0"); + EXPECT_EQ(low.Get(), 10); + EXPECT_EQ(high.Get(), 10); + ParseFieldTrial({&low, &high}, "low:inf,high:nan"); + EXPECT_EQ(low.Get(), 10); + EXPECT_EQ(high.Get(), 10); + ParseFieldTrial({&low, &high}, "low:20,high:20"); + EXPECT_EQ(low.Get(), 20); + EXPECT_EQ(high.Get(), 20); +} TEST(FieldTrialParserTest, ParsesOptionalParameters) { FieldTrialOptional max_count("c", absl::nullopt); ParseFieldTrial({&max_count}, ""); diff --git a/rtc_base/experiments/field_trial_units.cc b/rtc_base/experiments/field_trial_units.cc index 8c201a6ee7..5311a3a941 100644 --- a/rtc_base/experiments/field_trial_units.cc +++ b/rtc_base/experiments/field_trial_units.cc @@ -87,6 +87,10 @@ template class FieldTrialParameter; template class FieldTrialParameter; template class FieldTrialParameter; +template class FieldTrialConstrained; +template class FieldTrialConstrained; +template class FieldTrialConstrained; + template class FieldTrialOptional; template class FieldTrialOptional; template class FieldTrialOptional; diff --git a/rtc_base/experiments/field_trial_units.h b/rtc_base/experiments/field_trial_units.h index 932c5cb450..af88f4a6c0 100644 --- a/rtc_base/experiments/field_trial_units.h +++ b/rtc_base/experiments/field_trial_units.h @@ -21,6 +21,10 @@ extern template class FieldTrialParameter; extern template class FieldTrialParameter; extern template class FieldTrialParameter; +extern template class FieldTrialConstrained; +extern template class FieldTrialConstrained; +extern template class FieldTrialConstrained; + extern template class FieldTrialOptional; extern template class FieldTrialOptional; extern template class FieldTrialOptional; diff --git a/rtc_base/experiments/field_trial_units_unittest.cc b/rtc_base/experiments/field_trial_units_unittest.cc index 80771d926a..57022c2f23 100644 --- a/rtc_base/experiments/field_trial_units_unittest.cc +++ b/rtc_base/experiments/field_trial_units_unittest.cc @@ -58,5 +58,25 @@ TEST(FieldTrialParserUnitsTest, ParsesOtherUnitParameters) { EXPECT_EQ(*exp.max_buffer.GetOptional(), DataSize::bytes(8)); EXPECT_EQ(exp.period.Get(), TimeDelta::ms(300)); } +TEST(FieldTrialParserUnitsTest, IgnoresOutOfRange) { + FieldTrialConstrained rate("r", DataRate::kbps(30), + DataRate::kbps(10), DataRate::kbps(100)); + FieldTrialConstrained delta("d", TimeDelta::ms(30), + TimeDelta::ms(10), TimeDelta::ms(100)); + FieldTrialConstrained size( + "s", DataSize::bytes(30), DataSize::bytes(10), DataSize::bytes(100)); + ParseFieldTrial({&rate, &delta, &size}, "r:0,d:0,s:0"); + EXPECT_EQ(rate->kbps(), 30); + EXPECT_EQ(delta->ms(), 30); + EXPECT_EQ(size->bytes(), 30); + ParseFieldTrial({&rate, &delta, &size}, "r:300,d:300,s:300"); + EXPECT_EQ(rate->kbps(), 30); + EXPECT_EQ(delta->ms(), 30); + EXPECT_EQ(size->bytes(), 30); + ParseFieldTrial({&rate, &delta, &size}, "r:50,d:50,s:50"); + EXPECT_EQ(rate->kbps(), 50); + EXPECT_EQ(delta->ms(), 50); + EXPECT_EQ(size->bytes(), 50); +} } // namespace webrtc