xref: /aosp_15_r20/system/server_configurable_flags/aconfigd/tests/AconfigdJavaUtilsTest.java (revision 207333786ba243bc7d4d69ef6b05487aa7071806)
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.aconfigd.test;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.aconfigd.Aconfigd.StorageRequestMessage;
24 import android.aconfigd.Aconfigd.StorageRequestMessages;
25 import android.aconfigd.Aconfigd.StorageReturnMessage;
26 import android.aconfigd.Aconfigd.StorageReturnMessages;
27 import android.aconfigd.AconfigdClientSocket;
28 import android.aconfigd.AconfigdFlagInfo;
29 import android.aconfigd.AconfigdJavaUtils;
30 import android.util.proto.ProtoOutputStream;
31 
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.junit.runners.JUnit4;
35 
36 import java.io.ByteArrayInputStream;
37 import java.io.ByteArrayOutputStream;
38 import java.io.InputStream;
39 import java.util.Arrays;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.function.Function;
43 
44 @RunWith(JUnit4.class)
45 public class AconfigdJavaUtilsTest {
46 
47     @Test
testListFlagsValueInNewStorage_singleFlag()48     public void testListFlagsValueInNewStorage_singleFlag() throws Exception {
49         String packageName = "android.acondigd.test";
50         String flagName = "test_flag";
51         String serverValue = "";
52         String localValue = "";
53         String bootValue = "true";
54         String defaultValue = "true";
55         boolean hasServerOverride = false;
56         boolean isReadWrite = false;
57         boolean hasLocalOverride = false;
58 
59         AconfigdFlagInfo expectedRev =
60                 AconfigdFlagInfo.newBuilder()
61                         .setBootFlagValue(bootValue)
62                         .setDefaultFlagValue(defaultValue)
63                         .setFlagName(flagName)
64                         .setHasLocalOverride(hasLocalOverride)
65                         .setHasServerOverride(hasServerOverride)
66                         .setIsReadWrite(isReadWrite)
67                         .setLocalFlagValue(localValue)
68                         .setPackageName(packageName)
69                         .setServerFlagValue(serverValue)
70                         .build();
71 
72         ProtoOutputStream serverReturn = writeListFlagsRequest(Arrays.asList(expectedRev));
73 
74         ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize());
75         buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize());
76 
77         AconfigdClientSocket localSocket =
78                 new FakeAconfigdClientSocketImpl(
79                         input -> new ByteArrayInputStream(buffer.toByteArray()));
80 
81         Map<String, AconfigdFlagInfo> flagMap =
82                 AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
83         assertTrue(flagMap.containsKey(expectedRev.getFullFlagName()));
84         assertEquals(expectedRev, flagMap.get(expectedRev.getFullFlagName()));
85     }
86 
87     @Test
testListFlagsValueInNewStorage_multiFlags()88     public void testListFlagsValueInNewStorage_multiFlags() throws Exception {
89         String packageName = "android.acondigd.test";
90         String flagName1 = "test_flag1";
91         String flagName2 = "test_flag2";
92         String serverValue = "";
93         String localValue = "";
94         String bootValue = "true";
95         String defaultValue = "true";
96         boolean hasServerOverride = false;
97         boolean isReadWrite = false;
98         boolean hasLocalOverride = false;
99 
100         AconfigdFlagInfo expectedRev1 =
101                 AconfigdFlagInfo.newBuilder()
102                         .setBootFlagValue(bootValue)
103                         .setDefaultFlagValue(defaultValue)
104                         .setFlagName(flagName1)
105                         .setHasLocalOverride(hasLocalOverride)
106                         .setHasServerOverride(hasServerOverride)
107                         .setIsReadWrite(isReadWrite)
108                         .setLocalFlagValue(localValue)
109                         .setPackageName(packageName)
110                         .setServerFlagValue(serverValue)
111                         .build();
112 
113         AconfigdFlagInfo expectedRev2 =
114                 AconfigdFlagInfo.newBuilder()
115                         .setBootFlagValue(bootValue)
116                         .setDefaultFlagValue(defaultValue)
117                         .setFlagName(flagName2)
118                         .setHasLocalOverride(hasLocalOverride)
119                         .setHasServerOverride(hasServerOverride)
120                         .setIsReadWrite(isReadWrite)
121                         .setLocalFlagValue(localValue)
122                         .setPackageName(packageName)
123                         .setServerFlagValue(serverValue)
124                         .build();
125 
126         ProtoOutputStream serverReturn =
127                 writeListFlagsRequest(Arrays.asList(expectedRev1, expectedRev2));
128 
129         ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize());
130         buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize());
131 
132         AconfigdClientSocket localSocket =
133                 new FakeAconfigdClientSocketImpl(
134                         input -> new ByteArrayInputStream(buffer.toByteArray()));
135 
136         Map<String, AconfigdFlagInfo> flagMap =
137                 AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
138         assertTrue(flagMap.containsKey(expectedRev1.getFullFlagName()));
139         assertTrue(flagMap.containsKey(expectedRev2.getFullFlagName()));
140         assertEquals(expectedRev1, flagMap.get(expectedRev1.getFullFlagName()));
141         assertEquals(expectedRev2, flagMap.get(expectedRev2.getFullFlagName()));
142     }
143 
144     @Test
testListFlagsValueInNewStorage_errorMessage()145     public void testListFlagsValueInNewStorage_errorMessage() throws Exception {
146         ProtoOutputStream serverReturn = new ProtoOutputStream();
147         String expectErrorMessage = "invalid";
148         long msgsToken = serverReturn.start(StorageReturnMessages.MSGS);
149         serverReturn.write(StorageReturnMessage.ERROR_MESSAGE, expectErrorMessage);
150         serverReturn.end(msgsToken);
151 
152         ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize());
153         buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize());
154 
155         AconfigdClientSocket localSocket =
156                 new FakeAconfigdClientSocketImpl(
157                         input -> new ByteArrayInputStream(buffer.toByteArray()));
158 
159         Map<String, AconfigdFlagInfo> flagMap =
160                 AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
161         assertTrue(flagMap.isEmpty());
162     }
163 
164     @Test
testListFlagsValueInNewStorage_checkRequest()165     public void testListFlagsValueInNewStorage_checkRequest() throws Exception {
166 
167         ProtoOutputStream expectRequests = new ProtoOutputStream();
168         long msgsToken = expectRequests.start(StorageRequestMessages.MSGS);
169         long msgToken = expectRequests.start(StorageRequestMessage.LIST_STORAGE_MESSAGE);
170         expectRequests.write(StorageRequestMessage.ListStorageMessage.ALL, 1);
171         expectRequests.end(msgToken);
172         expectRequests.end(msgsToken);
173 
174         ProtoOutputStream serverReturn = new ProtoOutputStream();
175         String expectErrorMessage = "invalid";
176         msgsToken = serverReturn.start(StorageReturnMessages.MSGS);
177         serverReturn.write(StorageReturnMessage.ERROR_MESSAGE, expectErrorMessage);
178         serverReturn.end(msgsToken);
179 
180         ByteArrayOutputStream buffer = new ByteArrayOutputStream(serverReturn.getRawSize());
181         buffer.write(serverReturn.getBytes(), 0, serverReturn.getRawSize());
182 
183         AconfigdClientSocket localSocket =
184                 new FakeAconfigdClientSocketImpl(
185                         input -> {
186                             assertArrayEquals(expectRequests.getBytes(), input);
187                             return new ByteArrayInputStream(buffer.toByteArray());
188                         });
189 
190         Map<String, AconfigdFlagInfo> flagMap =
191                 AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
192         assertTrue(flagMap.isEmpty());
193     }
194 
writeListFlagsRequest(List<AconfigdFlagInfo> flags)195     private ProtoOutputStream writeListFlagsRequest(List<AconfigdFlagInfo> flags) {
196         ProtoOutputStream serverReturn = new ProtoOutputStream();
197         long msgsToken = serverReturn.start(StorageReturnMessages.MSGS);
198         long listToken = serverReturn.start(StorageReturnMessage.LIST_STORAGE_MESSAGE);
199 
200         for (AconfigdFlagInfo flag : flags) {
201             long flagToken =
202                     serverReturn.start(StorageReturnMessage.ListStorageReturnMessage.FLAGS);
203             serverReturn.write(
204                     StorageReturnMessage.FlagQueryReturnMessage.PACKAGE_NAME,
205                     flag.getPackageName());
206             serverReturn.write(
207                     StorageReturnMessage.FlagQueryReturnMessage.FLAG_NAME, flag.getFlagName());
208             serverReturn.write(
209                     StorageReturnMessage.FlagQueryReturnMessage.SERVER_FLAG_VALUE,
210                     flag.getServerFlagValue());
211             serverReturn.write(
212                     StorageReturnMessage.FlagQueryReturnMessage.LOCAL_FLAG_VALUE,
213                     flag.getLocalFlagValue());
214             serverReturn.write(
215                     StorageReturnMessage.FlagQueryReturnMessage.BOOT_FLAG_VALUE,
216                     flag.getBootFlagValue());
217             serverReturn.write(
218                     StorageReturnMessage.FlagQueryReturnMessage.DEFAULT_FLAG_VALUE,
219                     flag.getDefaultFlagValue());
220             serverReturn.write(
221                     StorageReturnMessage.FlagQueryReturnMessage.HAS_SERVER_OVERRIDE,
222                     flag.getHasServerOverride());
223             serverReturn.write(
224                     StorageReturnMessage.FlagQueryReturnMessage.IS_READWRITE,
225                     flag.getIsReadWrite());
226             serverReturn.write(
227                     StorageReturnMessage.FlagQueryReturnMessage.HAS_LOCAL_OVERRIDE,
228                     flag.getHasLocalOverride());
229             serverReturn.end(flagToken);
230         }
231 
232         serverReturn.end(listToken);
233         serverReturn.end(msgsToken);
234         return serverReturn;
235     }
236 
237     private class FakeAconfigdClientSocketImpl implements AconfigdClientSocket {
238         private Function<byte[], InputStream> mSendFunc;
239 
FakeAconfigdClientSocketImpl(Function<byte[], InputStream> sendFunc)240         FakeAconfigdClientSocketImpl(Function<byte[], InputStream> sendFunc) {
241             mSendFunc = sendFunc;
242         }
243 
244         @Override
send(byte[] requests)245         public InputStream send(byte[] requests) {
246             return mSendFunc.apply(requests);
247         }
248 
249         @Override
close()250         public void close() {
251             return;
252         }
253     }
254 }
255