Add safeguard for modifying POLICY_EXEMPT_FIELD_TRIALS
This will make it harder to inadvertently register new field trials in
the wrong collection. This has happened before, see 88a8e44a51 ("Remove
nonexempt field trials from POLICY_EXEMPT_FIELD_TRIALS") for example.
Additionally, field trials will now also be validated by default before
a C++ header is generated.
Bug: None
Change-Id: I298c1345d48a522ecb95fd0f0e09834c8bdff40a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/346543
Reviewed-by: Jeremy Leconte <jleconte@google.com>
Commit-Queue: Emil Lundmark <lndmrk@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42034}
diff --git a/experiments/field_trials.py b/experiments/field_trials.py
index a174367..3e65411 100755
--- a/experiments/field_trials.py
+++ b/experiments/field_trials.py
@@ -10,6 +10,7 @@
import datetime
from datetime import date
+import hashlib
import sys
from typing import FrozenSet, List, Set
@@ -162,6 +163,8 @@
# These field trials precedes the policy in `g3doc/field-trials.md` and are
# therefore not required to follow it. Do not add any new field trials here.
+# If you remove an entry you should also update
+# POLICY_EXEMPT_FIELD_TRIALS_DIGEST.
POLICY_EXEMPT_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
# keep-sorted start
FieldTrial('UseTwccPlrForAna',
@@ -913,6 +916,9 @@
# keep-sorted end
]) # yapf: disable
+POLICY_EXEMPT_FIELD_TRIALS_DIGEST: str = \
+ '023f4ce749a699f0ab811093b9f568d604da28a8'
+
REGISTERED_FIELD_TRIALS: FrozenSet[FieldTrial] = ACTIVE_FIELD_TRIALS.union(
POLICY_EXEMPT_FIELD_TRIALS)
@@ -1013,6 +1019,17 @@
A list of explanations for invalid field trials.
"""
invalid = []
+
+ sha1 = hashlib.sha1()
+ for trial in sorted(POLICY_EXEMPT_FIELD_TRIALS, key=lambda f: f.key):
+ sha1.update(trial.key.encode('ascii'))
+ if sha1.hexdigest() != POLICY_EXEMPT_FIELD_TRIALS_DIGEST:
+ invalid.append(
+ 'POLICY_EXEMPT_FIELD_TRIALS has been modified. Please note that '
+ 'you must not add any new entries there. If you removed an entry '
+ 'you should also update POLICY_EXEMPT_FIELD_TRIALS_DIGEST. The'
+ f'new digest is "{sha1.hexdigest()}".')
+
for trial in field_trials:
if not trial.key.startswith('WebRTC-'):
invalid.append(f'{trial.key} does not start with "WebRTC-".')
@@ -1020,10 +1037,16 @@
invalid.append(f'{trial.key} must have an associated bug.')
if trial.end_date >= INDEFINITE:
invalid.append(f'{trial.key} must have an end date.')
+
return invalid
def cmd_header(args: argparse.Namespace) -> None:
+ if not args.no_validation:
+ if errors := validate_field_trials():
+ print('\n'.join(sorted(errors)))
+ sys.exit(1)
+
args.output.write(registry_header())
@@ -1070,6 +1093,12 @@
type=argparse.FileType('w'),
required=False,
help='output file')
+ parser_header.add_argument(
+ '--no-validation',
+ default=False,
+ action='store_true',
+ required=False,
+ help='whether to validate the field trials before writing')
parser_header.set_defaults(cmd=cmd_header)
parser_expired = subcommand.add_parser(