1*20733378SAndroid Build Coastguard Worker /* 2*20733378SAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project 3*20733378SAndroid Build Coastguard Worker * 4*20733378SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*20733378SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*20733378SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*20733378SAndroid Build Coastguard Worker * 8*20733378SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*20733378SAndroid Build Coastguard Worker * 10*20733378SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*20733378SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*20733378SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*20733378SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*20733378SAndroid Build Coastguard Worker * limitations under the License. 15*20733378SAndroid Build Coastguard Worker */ 16*20733378SAndroid Build Coastguard Worker 17*20733378SAndroid Build Coastguard Worker package android.aconfigd.test; 18*20733378SAndroid Build Coastguard Worker 19*20733378SAndroid Build Coastguard Worker import static org.junit.Assert.assertArrayEquals; 20*20733378SAndroid Build Coastguard Worker import static org.junit.Assert.assertEquals; 21*20733378SAndroid Build Coastguard Worker import static org.junit.Assert.assertTrue; 22*20733378SAndroid Build Coastguard Worker 23*20733378SAndroid Build Coastguard Worker import android.aconfigd.Aconfigd.StorageRequestMessage; 24*20733378SAndroid Build Coastguard Worker import android.aconfigd.Aconfigd.StorageRequestMessages; 25*20733378SAndroid Build Coastguard Worker import android.aconfigd.Aconfigd.StorageReturnMessage; 26*20733378SAndroid Build Coastguard Worker import android.aconfigd.Aconfigd.StorageReturnMessages; 27*20733378SAndroid Build Coastguard Worker import android.aconfigd.AconfigdClientSocket; 28*20733378SAndroid Build Coastguard Worker import android.aconfigd.AconfigdFlagInfo; 29*20733378SAndroid Build Coastguard Worker import android.aconfigd.AconfigdJavaUtils; 30*20733378SAndroid Build Coastguard Worker import android.util.proto.ProtoOutputStream; 31*20733378SAndroid Build Coastguard Worker 32*20733378SAndroid Build Coastguard Worker import org.junit.Test; 33*20733378SAndroid Build Coastguard Worker import org.junit.runner.RunWith; 34*20733378SAndroid Build Coastguard Worker import org.junit.runners.JUnit4; 35*20733378SAndroid Build Coastguard Worker 36*20733378SAndroid Build Coastguard Worker import java.io.ByteArrayInputStream; 37*20733378SAndroid Build Coastguard Worker import java.io.ByteArrayOutputStream; 38*20733378SAndroid Build Coastguard Worker import java.io.InputStream; 39*20733378SAndroid Build Coastguard Worker import java.util.Arrays; 40*20733378SAndroid Build Coastguard Worker import java.util.List; 41*20733378SAndroid Build Coastguard Worker import java.util.Map; 42*20733378SAndroid Build Coastguard Worker import java.util.function.Function; 43*20733378SAndroid Build Coastguard Worker 44*20733378SAndroid Build Coastguard Worker @RunWith(JUnit4.class) 45*20733378SAndroid Build Coastguard Worker public class AconfigdJavaUtilsTest { 46*20733378SAndroid Build Coastguard Worker 47*20733378SAndroid Build Coastguard Worker @Test testListFlagsValueInNewStorage_singleFlag()48*20733378SAndroid Build Coastguard Worker public void testListFlagsValueInNewStorage_singleFlag() throws Exception { 49*20733378SAndroid Build Coastguard Worker String packageName = "android.acondigd.test"; 50*20733378SAndroid Build Coastguard Worker String flagName = "test_flag"; 51*20733378SAndroid Build Coastguard Worker String serverValue = ""; 52*20733378SAndroid Build Coastguard Worker String localValue = ""; 53*20733378SAndroid Build Coastguard Worker String bootValue = "true"; 54*20733378SAndroid Build Coastguard Worker String defaultValue = "true"; 55*20733378SAndroid Build Coastguard Worker boolean hasServerOverride = false; 56*20733378SAndroid Build Coastguard Worker boolean isReadWrite = false; 57*20733378SAndroid Build Coastguard Worker boolean hasLocalOverride = false; 58*20733378SAndroid Build Coastguard Worker 59*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo expectedRev = 60*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo.newBuilder() 61*20733378SAndroid Build Coastguard Worker .setBootFlagValue(bootValue) 62*20733378SAndroid Build Coastguard Worker .setDefaultFlagValue(defaultValue) 63*20733378SAndroid Build Coastguard Worker .setFlagName(flagName) 64*20733378SAndroid Build Coastguard Worker .setHasLocalOverride(hasLocalOverride) 65*20733378SAndroid Build Coastguard Worker .setHasServerOverride(hasServerOverride) 66*20733378SAndroid Build Coastguard Worker .setIsReadWrite(isReadWrite) 67*20733378SAndroid Build Coastguard Worker .setLocalFlagValue(localValue) 68*20733378SAndroid Build Coastguard Worker .setPackageName(packageName) 69*20733378SAndroid Build Coastguard Worker .setServerFlagValue(serverValue) 70*20733378SAndroid Build Coastguard Worker .build(); 71*20733378SAndroid Build Coastguard Worker 72*20733378SAndroid Build Coastguard Worker ProtoOutputStream serverReturn = writeListFlagsRequest(Arrays.asList(expectedRev)); 73*20733378SAndroid Build Coastguard Worker 74*20733378SAndroid Build Coastguard Worker ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize()); 75*20733378SAndroid Build Coastguard Worker buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize()); 76*20733378SAndroid Build Coastguard Worker 77*20733378SAndroid Build Coastguard Worker AconfigdClientSocket localSocket = 78*20733378SAndroid Build Coastguard Worker new FakeAconfigdClientSocketImpl( 79*20733378SAndroid Build Coastguard Worker input -> new ByteArrayInputStream(buffer.toByteArray())); 80*20733378SAndroid Build Coastguard Worker 81*20733378SAndroid Build Coastguard Worker Map<String, AconfigdFlagInfo> flagMap = 82*20733378SAndroid Build Coastguard Worker AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket); 83*20733378SAndroid Build Coastguard Worker assertTrue(flagMap.containsKey(expectedRev.getFullFlagName())); 84*20733378SAndroid Build Coastguard Worker assertEquals(expectedRev, flagMap.get(expectedRev.getFullFlagName())); 85*20733378SAndroid Build Coastguard Worker } 86*20733378SAndroid Build Coastguard Worker 87*20733378SAndroid Build Coastguard Worker @Test testListFlagsValueInNewStorage_multiFlags()88*20733378SAndroid Build Coastguard Worker public void testListFlagsValueInNewStorage_multiFlags() throws Exception { 89*20733378SAndroid Build Coastguard Worker String packageName = "android.acondigd.test"; 90*20733378SAndroid Build Coastguard Worker String flagName1 = "test_flag1"; 91*20733378SAndroid Build Coastguard Worker String flagName2 = "test_flag2"; 92*20733378SAndroid Build Coastguard Worker String serverValue = ""; 93*20733378SAndroid Build Coastguard Worker String localValue = ""; 94*20733378SAndroid Build Coastguard Worker String bootValue = "true"; 95*20733378SAndroid Build Coastguard Worker String defaultValue = "true"; 96*20733378SAndroid Build Coastguard Worker boolean hasServerOverride = false; 97*20733378SAndroid Build Coastguard Worker boolean isReadWrite = false; 98*20733378SAndroid Build Coastguard Worker boolean hasLocalOverride = false; 99*20733378SAndroid Build Coastguard Worker 100*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo expectedRev1 = 101*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo.newBuilder() 102*20733378SAndroid Build Coastguard Worker .setBootFlagValue(bootValue) 103*20733378SAndroid Build Coastguard Worker .setDefaultFlagValue(defaultValue) 104*20733378SAndroid Build Coastguard Worker .setFlagName(flagName1) 105*20733378SAndroid Build Coastguard Worker .setHasLocalOverride(hasLocalOverride) 106*20733378SAndroid Build Coastguard Worker .setHasServerOverride(hasServerOverride) 107*20733378SAndroid Build Coastguard Worker .setIsReadWrite(isReadWrite) 108*20733378SAndroid Build Coastguard Worker .setLocalFlagValue(localValue) 109*20733378SAndroid Build Coastguard Worker .setPackageName(packageName) 110*20733378SAndroid Build Coastguard Worker .setServerFlagValue(serverValue) 111*20733378SAndroid Build Coastguard Worker .build(); 112*20733378SAndroid Build Coastguard Worker 113*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo expectedRev2 = 114*20733378SAndroid Build Coastguard Worker AconfigdFlagInfo.newBuilder() 115*20733378SAndroid Build Coastguard Worker .setBootFlagValue(bootValue) 116*20733378SAndroid Build Coastguard Worker .setDefaultFlagValue(defaultValue) 117*20733378SAndroid Build Coastguard Worker .setFlagName(flagName2) 118*20733378SAndroid Build Coastguard Worker .setHasLocalOverride(hasLocalOverride) 119*20733378SAndroid Build Coastguard Worker .setHasServerOverride(hasServerOverride) 120*20733378SAndroid Build Coastguard Worker .setIsReadWrite(isReadWrite) 121*20733378SAndroid Build Coastguard Worker .setLocalFlagValue(localValue) 122*20733378SAndroid Build Coastguard Worker .setPackageName(packageName) 123*20733378SAndroid Build Coastguard Worker .setServerFlagValue(serverValue) 124*20733378SAndroid Build Coastguard Worker .build(); 125*20733378SAndroid Build Coastguard Worker 126*20733378SAndroid Build Coastguard Worker ProtoOutputStream serverReturn = 127*20733378SAndroid Build Coastguard Worker writeListFlagsRequest(Arrays.asList(expectedRev1, expectedRev2)); 128*20733378SAndroid Build Coastguard Worker 129*20733378SAndroid Build Coastguard Worker ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize()); 130*20733378SAndroid Build Coastguard Worker buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize()); 131*20733378SAndroid Build Coastguard Worker 132*20733378SAndroid Build Coastguard Worker AconfigdClientSocket localSocket = 133*20733378SAndroid Build Coastguard Worker new FakeAconfigdClientSocketImpl( 134*20733378SAndroid Build Coastguard Worker input -> new ByteArrayInputStream(buffer.toByteArray())); 135*20733378SAndroid Build Coastguard Worker 136*20733378SAndroid Build Coastguard Worker Map<String, AconfigdFlagInfo> flagMap = 137*20733378SAndroid Build Coastguard Worker AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket); 138*20733378SAndroid Build Coastguard Worker assertTrue(flagMap.containsKey(expectedRev1.getFullFlagName())); 139*20733378SAndroid Build Coastguard Worker assertTrue(flagMap.containsKey(expectedRev2.getFullFlagName())); 140*20733378SAndroid Build Coastguard Worker assertEquals(expectedRev1, flagMap.get(expectedRev1.getFullFlagName())); 141*20733378SAndroid Build Coastguard Worker assertEquals(expectedRev2, flagMap.get(expectedRev2.getFullFlagName())); 142*20733378SAndroid Build Coastguard Worker } 143*20733378SAndroid Build Coastguard Worker 144*20733378SAndroid Build Coastguard Worker @Test testListFlagsValueInNewStorage_errorMessage()145*20733378SAndroid Build Coastguard Worker public void testListFlagsValueInNewStorage_errorMessage() throws Exception { 146*20733378SAndroid Build Coastguard Worker ProtoOutputStream serverReturn = new ProtoOutputStream(); 147*20733378SAndroid Build Coastguard Worker String expectErrorMessage = "invalid"; 148*20733378SAndroid Build Coastguard Worker long msgsToken = serverReturn.start(StorageReturnMessages.MSGS); 149*20733378SAndroid Build Coastguard Worker serverReturn.write(StorageReturnMessage.ERROR_MESSAGE, expectErrorMessage); 150*20733378SAndroid Build Coastguard Worker serverReturn.end(msgsToken); 151*20733378SAndroid Build Coastguard Worker 152*20733378SAndroid Build Coastguard Worker ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize()); 153*20733378SAndroid Build Coastguard Worker buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize()); 154*20733378SAndroid Build Coastguard Worker 155*20733378SAndroid Build Coastguard Worker AconfigdClientSocket localSocket = 156*20733378SAndroid Build Coastguard Worker new FakeAconfigdClientSocketImpl( 157*20733378SAndroid Build Coastguard Worker input -> new ByteArrayInputStream(buffer.toByteArray())); 158*20733378SAndroid Build Coastguard Worker 159*20733378SAndroid Build Coastguard Worker Map<String, AconfigdFlagInfo> flagMap = 160*20733378SAndroid Build Coastguard Worker AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket); 161*20733378SAndroid Build Coastguard Worker assertTrue(flagMap.isEmpty()); 162*20733378SAndroid Build Coastguard Worker } 163*20733378SAndroid Build Coastguard Worker 164*20733378SAndroid Build Coastguard Worker @Test testListFlagsValueInNewStorage_checkRequest()165*20733378SAndroid Build Coastguard Worker public void testListFlagsValueInNewStorage_checkRequest() throws Exception { 166*20733378SAndroid Build Coastguard Worker 167*20733378SAndroid Build Coastguard Worker ProtoOutputStream expectRequests = new ProtoOutputStream(); 168*20733378SAndroid Build Coastguard Worker long msgsToken = expectRequests.start(StorageRequestMessages.MSGS); 169*20733378SAndroid Build Coastguard Worker long msgToken = expectRequests.start(StorageRequestMessage.LIST_STORAGE_MESSAGE); 170*20733378SAndroid Build Coastguard Worker expectRequests.write(StorageRequestMessage.ListStorageMessage.ALL, 1); 171*20733378SAndroid Build Coastguard Worker expectRequests.end(msgToken); 172*20733378SAndroid Build Coastguard Worker expectRequests.end(msgsToken); 173*20733378SAndroid Build Coastguard Worker 174*20733378SAndroid Build Coastguard Worker ProtoOutputStream serverReturn = new ProtoOutputStream(); 175*20733378SAndroid Build Coastguard Worker String expectErrorMessage = "invalid"; 176*20733378SAndroid Build Coastguard Worker msgsToken = serverReturn.start(StorageReturnMessages.MSGS); 177*20733378SAndroid Build Coastguard Worker serverReturn.write(StorageReturnMessage.ERROR_MESSAGE, expectErrorMessage); 178*20733378SAndroid Build Coastguard Worker serverReturn.end(msgsToken); 179*20733378SAndroid Build Coastguard Worker 180*20733378SAndroid Build Coastguard Worker ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize()); 181*20733378SAndroid Build Coastguard Worker buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize()); 182*20733378SAndroid Build Coastguard Worker 183*20733378SAndroid Build Coastguard Worker AconfigdClientSocket localSocket = 184*20733378SAndroid Build Coastguard Worker new FakeAconfigdClientSocketImpl( 185*20733378SAndroid Build Coastguard Worker input -> { 186*20733378SAndroid Build Coastguard Worker assertArrayEquals(expectRequests.getBytes(), input); 187*20733378SAndroid Build Coastguard Worker return new ByteArrayInputStream(buffer.toByteArray()); 188*20733378SAndroid Build Coastguard Worker }); 189*20733378SAndroid Build Coastguard Worker 190*20733378SAndroid Build Coastguard Worker Map<String, AconfigdFlagInfo> flagMap = 191*20733378SAndroid Build Coastguard Worker AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket); 192*20733378SAndroid Build Coastguard Worker assertTrue(flagMap.isEmpty()); 193*20733378SAndroid Build Coastguard Worker } 194*20733378SAndroid Build Coastguard Worker writeListFlagsRequest(List<AconfigdFlagInfo> flags)195*20733378SAndroid Build Coastguard Worker private ProtoOutputStream writeListFlagsRequest(List<AconfigdFlagInfo> flags) { 196*20733378SAndroid Build Coastguard Worker ProtoOutputStream serverReturn = new ProtoOutputStream(); 197*20733378SAndroid Build Coastguard Worker long msgsToken = serverReturn.start(StorageReturnMessages.MSGS); 198*20733378SAndroid Build Coastguard Worker long listToken = serverReturn.start(StorageReturnMessage.LIST_STORAGE_MESSAGE); 199*20733378SAndroid Build Coastguard Worker 200*20733378SAndroid Build Coastguard Worker for (AconfigdFlagInfo flag : flags) { 201*20733378SAndroid Build Coastguard Worker long flagToken = 202*20733378SAndroid Build Coastguard Worker serverReturn.start(StorageReturnMessage.ListStorageReturnMessage.FLAGS); 203*20733378SAndroid Build Coastguard Worker serverReturn.write( 204*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.PACKAGE_NAME, 205*20733378SAndroid Build Coastguard Worker flag.getPackageName()); 206*20733378SAndroid Build Coastguard Worker serverReturn.write( 207*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.FLAG_NAME, flag.getFlagName()); 208*20733378SAndroid Build Coastguard Worker serverReturn.write( 209*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.SERVER_FLAG_VALUE, 210*20733378SAndroid Build Coastguard Worker flag.getServerFlagValue()); 211*20733378SAndroid Build Coastguard Worker serverReturn.write( 212*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.LOCAL_FLAG_VALUE, 213*20733378SAndroid Build Coastguard Worker flag.getLocalFlagValue()); 214*20733378SAndroid Build Coastguard Worker serverReturn.write( 215*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.BOOT_FLAG_VALUE, 216*20733378SAndroid Build Coastguard Worker flag.getBootFlagValue()); 217*20733378SAndroid Build Coastguard Worker serverReturn.write( 218*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.DEFAULT_FLAG_VALUE, 219*20733378SAndroid Build Coastguard Worker flag.getDefaultFlagValue()); 220*20733378SAndroid Build Coastguard Worker serverReturn.write( 221*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.HAS_SERVER_OVERRIDE, 222*20733378SAndroid Build Coastguard Worker flag.getHasServerOverride()); 223*20733378SAndroid Build Coastguard Worker serverReturn.write( 224*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.IS_READWRITE, 225*20733378SAndroid Build Coastguard Worker flag.getIsReadWrite()); 226*20733378SAndroid Build Coastguard Worker serverReturn.write( 227*20733378SAndroid Build Coastguard Worker StorageReturnMessage.FlagQueryReturnMessage.HAS_LOCAL_OVERRIDE, 228*20733378SAndroid Build Coastguard Worker flag.getHasLocalOverride()); 229*20733378SAndroid Build Coastguard Worker serverReturn.end(flagToken); 230*20733378SAndroid Build Coastguard Worker } 231*20733378SAndroid Build Coastguard Worker 232*20733378SAndroid Build Coastguard Worker serverReturn.end(listToken); 233*20733378SAndroid Build Coastguard Worker serverReturn.end(msgsToken); 234*20733378SAndroid Build Coastguard Worker return serverReturn; 235*20733378SAndroid Build Coastguard Worker } 236*20733378SAndroid Build Coastguard Worker 237*20733378SAndroid Build Coastguard Worker private class FakeAconfigdClientSocketImpl implements AconfigdClientSocket { 238*20733378SAndroid Build Coastguard Worker private Function<byte[], InputStream> mSendFunc; 239*20733378SAndroid Build Coastguard Worker FakeAconfigdClientSocketImpl(Function<byte[], InputStream> sendFunc)240*20733378SAndroid Build Coastguard Worker FakeAconfigdClientSocketImpl(Function<byte[], InputStream> sendFunc) { 241*20733378SAndroid Build Coastguard Worker mSendFunc = sendFunc; 242*20733378SAndroid Build Coastguard Worker } 243*20733378SAndroid Build Coastguard Worker 244*20733378SAndroid Build Coastguard Worker @Override send(byte[] requests)245*20733378SAndroid Build Coastguard Worker public InputStream send(byte[] requests) { 246*20733378SAndroid Build Coastguard Worker return mSendFunc.apply(requests); 247*20733378SAndroid Build Coastguard Worker } 248*20733378SAndroid Build Coastguard Worker 249*20733378SAndroid Build Coastguard Worker @Override close()250*20733378SAndroid Build Coastguard Worker public void close() { 251*20733378SAndroid Build Coastguard Worker return; 252*20733378SAndroid Build Coastguard Worker } 253*20733378SAndroid Build Coastguard Worker } 254*20733378SAndroid Build Coastguard Worker } 255