blob: 1a3275c6e2bd4ed3afb9fdea76092ee9d0b63dc6 [file] [log] [blame]
Zhuoyao Zhang3ca7cef2024-10-31 22:07:31 +00001# Copyright 2024, The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import hashlib
16import logging
17import os
18
19
20def is_feature_enabled(
21 feature_name: str,
22 user_name: str,
23 enable_flag: str = None,
24 rollout_flag: str = None,
25) -> bool:
26 """Determine whether the given feature is enabled.
27
28 Whether a given feature is enabled or not depends on two flags: 1) the
29 enable_flag that explicitly enable/disable the feature and 2) the rollout_flag
30 that controls the rollout percentage.
31
32 Args:
33 feature_name: name of the feature.
34 user_name: system user name.
35 enable_flag: name of the env var that enables/disables the feature
36 explicitly.
37 rollout_flg: name of the env var that controls the rollout percentage, the
38 value stored in the env var should be an int between 0 and 100 string
39 """
40 if enable_flag:
41 if os.environ.get(enable_flag, "") == "false":
42 logging.info("feature: %s is disabled", feature_name)
43 return False
44
45 if os.environ.get(enable_flag, "") == "true":
46 logging.info("feature: %s is enabled", feature_name)
47 return True
48
49 if not rollout_flag:
50 return True
51
52 hash_object = hashlib.sha256()
53 hash_object.update((user_name + feature_name).encode("utf-8"))
54 hash_number = int(hash_object.hexdigest(), 16) % 100
55
56 roll_out_percentage = os.environ.get(rollout_flag, "0")
57 try:
58 percentage = int(roll_out_percentage)
59 if percentage < 0 or percentage > 100:
60 logging.warning(
61 "Rollout percentage: %s out of range, disable the feature.",
62 roll_out_percentage,
63 )
64 return False
65 return hash_number < percentage
66 except ValueError:
67 logging.warning(
68 "Invalid rollout percentage: %s, disable the feature.",
69 roll_out_percentage,
70 )
71 return False