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 android.aconfig.storage.test; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 22 import android.aconfig.DeviceProtosTestUtil; 23 import android.aconfig.nano.Aconfig.parsed_flag; 24 import android.aconfig.storage.AconfigStorageReadAPI; 25 import android.aconfig.storage.FlagReadContext; 26 import android.aconfig.storage.FlagReadContext.StoredFlagType; 27 import android.aconfig.storage.PackageReadContext; 28 import android.aconfig.storage.SipHasher13; 29 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.JUnit4; 33 34 import java.io.IOException; 35 import java.nio.MappedByteBuffer; 36 import java.util.ArrayList; 37 import java.util.List; 38 39 @RunWith(JUnit4.class) 40 public class AconfigStorageReadAPITest { 41 42 private String mStorageDir = "/data/local/tmp/aconfig_java_api_test"; 43 44 @Test testPackageContextQuery()45 public void testPackageContextQuery() { 46 MappedByteBuffer packageMap = null; 47 try { 48 packageMap = 49 AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/maps/mockup.package.map"); 50 } catch (IOException ex) { 51 assertTrue(ex.toString(), false); 52 } 53 assertTrue(packageMap != null); 54 55 try { 56 PackageReadContext context = 57 AconfigStorageReadAPI.getPackageReadContext( 58 packageMap, "com.android.aconfig.storage.test_1"); 59 assertEquals(context.mPackageId, 0); 60 assertEquals(context.mBooleanStartIndex, 0); 61 62 context = 63 AconfigStorageReadAPI.getPackageReadContext( 64 packageMap, "com.android.aconfig.storage.test_2"); 65 assertEquals(context.mPackageId, 1); 66 assertEquals(context.mBooleanStartIndex, 3); 67 68 context = 69 AconfigStorageReadAPI.getPackageReadContext( 70 packageMap, "com.android.aconfig.storage.test_4"); 71 assertEquals(context.mPackageId, 2); 72 assertEquals(context.mBooleanStartIndex, 6); 73 } catch (IOException ex) { 74 assertTrue(ex.toString(), false); 75 } 76 } 77 78 @Test testNonExistPackageContextQuery()79 public void testNonExistPackageContextQuery() { 80 MappedByteBuffer packageMap = null; 81 try { 82 packageMap = 83 AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/maps/mockup.package.map"); 84 } catch (IOException ex) { 85 assertTrue(ex.toString(), false); 86 } 87 assertTrue(packageMap != null); 88 89 try { 90 PackageReadContext context = 91 AconfigStorageReadAPI.getPackageReadContext(packageMap, "unknown"); 92 assertEquals(context.mPackageId, -1); 93 assertEquals(context.mBooleanStartIndex, -1); 94 } catch (IOException ex) { 95 assertTrue(ex.toString(), false); 96 } 97 } 98 99 @Test testFlagContextQuery()100 public void testFlagContextQuery() { 101 MappedByteBuffer flagMap = null; 102 try { 103 flagMap = AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/maps/mockup.flag.map"); 104 } catch (IOException ex) { 105 assertTrue(ex.toString(), false); 106 } 107 assertTrue(flagMap != null); 108 109 class Baseline { 110 public int mPackageId; 111 public String mFlagName; 112 public StoredFlagType mFlagType; 113 public int mFlagIndex; 114 115 public Baseline( 116 int packageId, String flagName, StoredFlagType flagType, int flagIndex) { 117 mPackageId = packageId; 118 mFlagName = flagName; 119 mFlagType = flagType; 120 mFlagIndex = flagIndex; 121 } 122 } 123 124 List<Baseline> baselines = new ArrayList(); 125 baselines.add(new Baseline(0, "enabled_ro", StoredFlagType.ReadOnlyBoolean, 1)); 126 baselines.add(new Baseline(0, "enabled_rw", StoredFlagType.ReadWriteBoolean, 2)); 127 baselines.add(new Baseline(2, "enabled_rw", StoredFlagType.ReadWriteBoolean, 1)); 128 baselines.add(new Baseline(1, "disabled_rw", StoredFlagType.ReadWriteBoolean, 0)); 129 baselines.add(new Baseline(1, "enabled_fixed_ro", StoredFlagType.FixedReadOnlyBoolean, 1)); 130 baselines.add(new Baseline(1, "enabled_ro", StoredFlagType.ReadOnlyBoolean, 2)); 131 baselines.add(new Baseline(2, "enabled_fixed_ro", StoredFlagType.FixedReadOnlyBoolean, 0)); 132 baselines.add(new Baseline(0, "disabled_rw", StoredFlagType.ReadWriteBoolean, 0)); 133 134 try { 135 for (Baseline baseline : baselines) { 136 FlagReadContext context = 137 AconfigStorageReadAPI.getFlagReadContext( 138 flagMap, baseline.mPackageId, baseline.mFlagName); 139 assertEquals(context.mFlagType, baseline.mFlagType); 140 assertEquals(context.mFlagIndex, baseline.mFlagIndex); 141 } 142 } catch (IOException ex) { 143 assertTrue(ex.toString(), false); 144 } 145 } 146 147 @Test testNonExistFlagContextQuery()148 public void testNonExistFlagContextQuery() { 149 MappedByteBuffer flagMap = null; 150 try { 151 flagMap = AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/maps/mockup.flag.map"); 152 } catch (IOException ex) { 153 assertTrue(ex.toString(), false); 154 } 155 assertTrue(flagMap != null); 156 157 try { 158 FlagReadContext context = 159 AconfigStorageReadAPI.getFlagReadContext(flagMap, 0, "unknown"); 160 assertEquals(context.mFlagType, null); 161 assertEquals(context.mFlagIndex, -1); 162 163 context = AconfigStorageReadAPI.getFlagReadContext(flagMap, 3, "enabled_ro"); 164 assertEquals(context.mFlagType, null); 165 assertEquals(context.mFlagIndex, -1); 166 } catch (IOException ex) { 167 assertTrue(ex.toString(), false); 168 } 169 } 170 171 @Test testBooleanFlagValueQuery()172 public void testBooleanFlagValueQuery() { 173 MappedByteBuffer flagVal = null; 174 try { 175 flagVal = AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/boot/mockup.val"); 176 } catch (IOException ex) { 177 assertTrue(ex.toString(), false); 178 } 179 assertTrue(flagVal != null); 180 181 boolean[] baselines = {false, true, true, false, true, true, true, true}; 182 for (int i = 0; i < 8; ++i) { 183 try { 184 Boolean value = AconfigStorageReadAPI.getBooleanFlagValue(flagVal, i); 185 assertEquals(value, baselines[i]); 186 } catch (IOException ex) { 187 assertTrue(ex.toString(), false); 188 } 189 } 190 } 191 192 @Test testInvalidBooleanFlagValueQuery()193 public void testInvalidBooleanFlagValueQuery() { 194 MappedByteBuffer flagVal = null; 195 try { 196 flagVal = AconfigStorageReadAPI.mapStorageFile(mStorageDir + "/boot/mockup.val"); 197 } catch (IOException ex) { 198 assertTrue(ex.toString(), false); 199 } 200 assertTrue(flagVal != null); 201 202 try { 203 Boolean value = AconfigStorageReadAPI.getBooleanFlagValue(flagVal, 9); 204 assertTrue("should throw", false); 205 } catch (IOException ex) { 206 String expectedErrmsg = "invalid storage file byte offset"; 207 assertTrue(ex.toString(), ex.toString().contains(expectedErrmsg)); 208 } 209 } 210 211 @Test testRustJavaEqualHash()212 public void testRustJavaEqualHash() throws IOException { 213 List<parsed_flag> flags = DeviceProtosTestUtil.loadAndParseFlagProtos(); 214 for (parsed_flag flag : flags) { 215 String packageName = flag.package_; 216 String flagName = flag.name; 217 long rHash = AconfigStorageReadAPI.hash(packageName); 218 long jHash = SipHasher13.hash(packageName.getBytes()); 219 assertEquals(rHash, jHash); 220 221 String fullFlagName = packageName + "/" + flagName; 222 rHash = AconfigStorageReadAPI.hash(fullFlagName); 223 jHash = SipHasher13.hash(fullFlagName.getBytes()); 224 assertEquals(rHash, jHash); 225 } 226 } 227 } 228