1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.healthfitness.flags; 18 19 import static com.android.healthfitness.flags.AconfigFlagHelper.DB_VERSION_TO_DB_FLAG_MAP; 20 import static com.android.healthfitness.flags.AconfigFlagHelper.getDbVersion; 21 import static com.android.healthfitness.flags.AconfigFlagHelper.isCloudBackupRestoreEnabled; 22 import static com.android.healthfitness.flags.AconfigFlagHelper.isEcosystemMetricsEnabled; 23 import static com.android.healthfitness.flags.AconfigFlagHelper.isPersonalHealthRecordEnabled; 24 import static com.android.healthfitness.flags.DatabaseVersions.LAST_ROLLED_OUT_DB_VERSION; 25 26 import static com.google.common.truth.Truth.assertThat; 27 28 import static org.junit.Assert.assertTrue; 29 30 import android.platform.test.annotations.DisableFlags; 31 import android.platform.test.annotations.EnableFlags; 32 import android.platform.test.flag.junit.SetFlagsRule; 33 34 import androidx.test.ext.junit.runners.AndroidJUnit4; 35 36 import org.junit.ClassRule; 37 import org.junit.Rule; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.util.Map; 42 import java.util.function.BooleanSupplier; 43 44 @RunWith(AndroidJUnit4.class) 45 public class AconfigFlagHelperTest { 46 @ClassRule public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule(); 47 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 48 49 @Test 50 @DisableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) infraToGuardDbChangesDisabled()51 public void infraToGuardDbChangesDisabled() { 52 // clear the map to setup a hypothetical test case 53 DB_VERSION_TO_DB_FLAG_MAP.clear(); 54 // putting a very high DB version mapping to true to the map 55 DB_VERSION_TO_DB_FLAG_MAP.put(1000_000, () -> true); 56 57 // since FLAG_INFRA_TO_GUARD_DB_CHANGES is disabled, that very high version shouldn't be 58 // taken into account. 59 assertThat(getDbVersion()).isEqualTo(LAST_ROLLED_OUT_DB_VERSION); 60 } 61 62 @Test 63 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) 64 @DisableFlags(Flags.FLAG_PERSONAL_HEALTH_RECORD_DATABASE) infraToGuardDbChangesEnabled()65 public void infraToGuardDbChangesEnabled() { 66 // clear the map to setup a hypothetical test case 67 DB_VERSION_TO_DB_FLAG_MAP.clear(); 68 assertThat(getDbVersion()).isEqualTo(LAST_ROLLED_OUT_DB_VERSION); 69 } 70 71 @Test 72 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) readDbVersionToDbFlagMap_expectNoDbVersionSmallerThanBaseline()73 public void readDbVersionToDbFlagMap_expectNoDbVersionSmallerThanBaseline() { 74 // clear the map to setup a hypothetical test case 75 DB_VERSION_TO_DB_FLAG_MAP.clear(); 76 // The baseline is the DB version when go/hc-aconfig-and-db is first introduced, which is 77 // LAST_ROLLED_OUT_DB_VERSION. 78 int baseline = LAST_ROLLED_OUT_DB_VERSION; 79 80 // Initialize the map, it won't be empty after this method is called. 81 getDbVersion(); 82 83 for (int version : DB_VERSION_TO_DB_FLAG_MAP.keySet()) { 84 assertThat(version).isGreaterThan(baseline); 85 } 86 } 87 88 @Test 89 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) testGetDbVersion_true_true_true()90 public void testGetDbVersion_true_true_true() { 91 // clear the map to setup a hypothetical test case 92 DB_VERSION_TO_DB_FLAG_MAP.clear(); 93 // initialize DB_VERSION_TO_DB_FLAG_MAP, so it won't be empty when getDbVersion() is called, 94 // so the entries created in this test will be used. 95 DB_VERSION_TO_DB_FLAG_MAP.put(1, () -> true); 96 DB_VERSION_TO_DB_FLAG_MAP.put(2, () -> true); 97 DB_VERSION_TO_DB_FLAG_MAP.put(3, () -> true); 98 99 assertThat(getDbVersion()).isEqualTo(3); 100 } 101 102 @Test 103 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) testGetDbVersion_true_false_true()104 public void testGetDbVersion_true_false_true() { 105 // clear the map to setup a hypothetical test case 106 DB_VERSION_TO_DB_FLAG_MAP.clear(); 107 // initialize DB_VERSION_TO_DB_FLAG_MAP, so it won't be empty when getDbVersion() is called, 108 // so the entries created in this test will be used. 109 DB_VERSION_TO_DB_FLAG_MAP.put(1, () -> true); 110 DB_VERSION_TO_DB_FLAG_MAP.put(2, () -> false); 111 DB_VERSION_TO_DB_FLAG_MAP.put(3, () -> true); 112 113 assertThat(getDbVersion()).isEqualTo(1); 114 } 115 116 @Test 117 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) testGetDbVersion_true_false_false()118 public void testGetDbVersion_true_false_false() { 119 // clear the map to setup a hypothetical test case 120 DB_VERSION_TO_DB_FLAG_MAP.clear(); 121 // initialize DB_VERSION_TO_DB_FLAG_MAP, so it won't be empty when getDbVersion() is called, 122 // so the entries created in this test will be used. 123 DB_VERSION_TO_DB_FLAG_MAP.put(1, () -> true); 124 DB_VERSION_TO_DB_FLAG_MAP.put(2, () -> false); 125 DB_VERSION_TO_DB_FLAG_MAP.put(3, () -> false); 126 127 assertThat(getDbVersion()).isEqualTo(1); 128 } 129 130 @Test 131 @EnableFlags({Flags.FLAG_INFRA_TO_GUARD_DB_CHANGES}) testToEnsureLastRolledOutDbVersionIsSetCorrectly()132 public void testToEnsureLastRolledOutDbVersionIsSetCorrectly() { 133 // This test is to prevent the case where the instructions in 134 // go/hc-mainline-dev/trunk_stable/add-db-changes aren't followed correctly. 135 // Specifically, it prevents the case in which a DB version is set to 136 // LAST_ROLLED_OUT_DB_VERSION without being guarded with an aconfig flag while there are 137 // DB versions being rolled out. 138 // For example, if: 139 // - LAST_ROLLED_OUT_DB_VERSION is currently 14 140 // - DB_VERSION_TO_DB_FLAG_MAP contains a single entry of 15 => false 141 // Now, if a version X = 16 is added to DatabaseVersions.java, and X is assigned to 142 // LAST_ROLLED_OUT_DB_VERSION, then this test would fail. 143 for (Map.Entry<Integer, BooleanSupplier> entry : DB_VERSION_TO_DB_FLAG_MAP.entrySet()) { 144 int dbVersion = entry.getKey(); 145 boolean flagValue = entry.getValue().getAsBoolean(); 146 if (!flagValue) { // flagValue being `false` means the feature hasn't been rolled out 147 // If a feature hasn't been rolled out, then its DB version must be greater than 148 // the last rolled out DB version. 149 assertTrue( 150 String.format( 151 "DB version %d hasn't been rolled out yet, it's likely a mistake to" 152 + " set DatabaseVersions#LAST_ROLLED_OUT_DB_VERSION to a " 153 + "number" 154 + " greater than %d. Make sure you follow the " 155 + "instructions in" 156 + " go/hc-mainline-dev/trunk_stable/add-db-changes.", 157 dbVersion, dbVersion), 158 dbVersion > LAST_ROLLED_OUT_DB_VERSION); 159 } 160 } 161 } 162 163 @Test 164 @EnableFlags({Flags.FLAG_PERSONAL_HEALTH_RECORD_DATABASE, Flags.FLAG_PERSONAL_HEALTH_RECORD}) phr_featureFlagTrueAndDbFlagTrue_expectTrue()165 public void phr_featureFlagTrueAndDbFlagTrue_expectTrue() { 166 assertThat(isPersonalHealthRecordEnabled()).isTrue(); 167 } 168 169 @Test 170 @DisableFlags({Flags.FLAG_PERSONAL_HEALTH_RECORD_DATABASE, Flags.FLAG_PERSONAL_HEALTH_RECORD}) phr_featureFlagFalseAndDbFlagFalse_expectFalse()171 public void phr_featureFlagFalseAndDbFlagFalse_expectFalse() { 172 assertThat(isPersonalHealthRecordEnabled()).isFalse(); 173 } 174 175 @Test 176 @DisableFlags(Flags.FLAG_PERSONAL_HEALTH_RECORD) 177 @EnableFlags(Flags.FLAG_PERSONAL_HEALTH_RECORD_DATABASE) phr_featureFlagFalseAndDbTrue_expectFalse()178 public void phr_featureFlagFalseAndDbTrue_expectFalse() { 179 assertThat(isPersonalHealthRecordEnabled()).isFalse(); 180 } 181 182 @Test 183 @EnableFlags(Flags.FLAG_PERSONAL_HEALTH_RECORD) 184 @DisableFlags(Flags.FLAG_PERSONAL_HEALTH_RECORD_DATABASE) phr_featureFlagTrueAndDbFalse_expectFalse()185 public void phr_featureFlagTrueAndDbFalse_expectFalse() { 186 assertThat(isPersonalHealthRecordEnabled()).isFalse(); 187 } 188 189 @Test 190 @EnableFlags(Flags.FLAG_ECOSYSTEM_METRICS_DB_CHANGES) 191 @DisableFlags(Flags.FLAG_ECOSYSTEM_METRICS) isEcosystemMetricsEnabled_featureFlagOff_expectFalse()192 public void isEcosystemMetricsEnabled_featureFlagOff_expectFalse() { 193 assertThat(isEcosystemMetricsEnabled()).isFalse(); 194 } 195 196 @Test 197 @EnableFlags(Flags.FLAG_ECOSYSTEM_METRICS) 198 @DisableFlags(Flags.FLAG_ECOSYSTEM_METRICS_DB_CHANGES) isEcosystemMetricsEnabled_dbFlagOff_expectFalse()199 public void isEcosystemMetricsEnabled_dbFlagOff_expectFalse() { 200 assertThat(isEcosystemMetricsEnabled()).isFalse(); 201 } 202 203 @Test 204 @EnableFlags({ 205 Flags.FLAG_ECOSYSTEM_METRICS, 206 Flags.FLAG_ECOSYSTEM_METRICS_DB_CHANGES, 207 }) isEcosystemMetricsEnabled_bothFlagsOn_expectTrue()208 public void isEcosystemMetricsEnabled_bothFlagsOn_expectTrue() { 209 assertThat(isEcosystemMetricsEnabled()).isTrue(); 210 } 211 212 @Test 213 @EnableFlags({ 214 Flags.FLAG_CLOUD_BACKUP_AND_RESTORE, 215 Flags.FLAG_CLOUD_BACKUP_AND_RESTORE_DB, 216 Flags.FLAG_ECOSYSTEM_METRICS_DB_CHANGES 217 }) cloudBackupAndRestore_featureFlagTrueAndDbFlagTrue_expectTrue()218 public void cloudBackupAndRestore_featureFlagTrueAndDbFlagTrue_expectTrue() { 219 assertThat(isCloudBackupRestoreEnabled()).isTrue(); 220 } 221 222 @Test 223 @DisableFlags({Flags.FLAG_CLOUD_BACKUP_AND_RESTORE, Flags.FLAG_CLOUD_BACKUP_AND_RESTORE_DB}) cloudBackupAndRestore_featureFlagFalseAndDbFlagFalse_expectFalse()224 public void cloudBackupAndRestore_featureFlagFalseAndDbFlagFalse_expectFalse() { 225 assertThat(isCloudBackupRestoreEnabled()).isFalse(); 226 } 227 228 @Test 229 @DisableFlags(Flags.FLAG_CLOUD_BACKUP_AND_RESTORE) 230 @EnableFlags(Flags.FLAG_CLOUD_BACKUP_AND_RESTORE_DB) cloudBackupAndRestore_featureFlagFalseAndDbTrue_expectFalse()231 public void cloudBackupAndRestore_featureFlagFalseAndDbTrue_expectFalse() { 232 assertThat(isCloudBackupRestoreEnabled()).isFalse(); 233 } 234 235 @Test 236 @EnableFlags(Flags.FLAG_CLOUD_BACKUP_AND_RESTORE) 237 @DisableFlags(Flags.FLAG_CLOUD_BACKUP_AND_RESTORE_DB) cloudBackupAndRestore_featureFlagTrueAndDbFalse_expectFalse()238 public void cloudBackupAndRestore_featureFlagTrueAndDbFalse_expectFalse() { 239 assertThat(isCloudBackupRestoreEnabled()).isFalse(); 240 } 241 } 242