1 /*
2  * Copyright (C) 2023 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.platform.test.flag.junit.host;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertThrows;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.when;
24 
25 import android.aconfig.Aconfig;
26 import android.aconfig.Aconfig.parsed_flags;
27 import android.platform.test.flag.junit.IFlagsValueProvider;
28 import android.platform.test.flag.util.FlagReadException;
29 
30 import com.android.tradefed.device.ITestDevice;
31 
32 import org.junit.Before;
33 import org.junit.Rule;
34 import org.junit.Test;
35 import org.junit.rules.TemporaryFolder;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.JUnit4;
38 import org.mockito.Mock;
39 import org.mockito.junit.MockitoJUnit;
40 import org.mockito.junit.MockitoRule;
41 
42 import java.io.File;
43 import java.io.FileOutputStream;
44 
45 @RunWith(JUnit4.class)
46 public class HostFlagsValueProviderTest {
47     private static final String DEVICE_CONFIG_LIST =
48             "namespace1/flag1=true\nnamespace1/flag2=false\nnamespace2/flag1=abc";
49     private static final parsed_flags ACONFIG_FLAGS =
50             parsed_flags
51                     .newBuilder()
52                     .addParsedFlag(
53                             Aconfig.parsed_flag
54                                     .newBuilder()
55                                     .setPackage("com.android.flags")
56                                     .setName("my_flag")
57                                     .setNamespace("cts")
58                                     .setDescription("A sample flag")
59                                     .addBug("12345678")
60                                     .setState(Aconfig.flag_state.DISABLED)
61                                     .setPermission(Aconfig.flag_permission.READ_WRITE))
62                     .build();
63 
64     @Rule public final MockitoRule mockito = MockitoJUnit.rule();
65     @Rule public final TemporaryFolder testFolder = new TemporaryFolder();
66 
67     @Mock private ITestDevice mTestDevice;
68 
69     private HostFlagsValueProvider mHostFlagsValueProvider;
70 
71     @Before
initHostFlagsValueProvider()72     public void initHostFlagsValueProvider() throws Exception {
73         File aconfigFlagsPbFile = testFolder.newFile();
74         ACONFIG_FLAGS.writeTo(new FileOutputStream(aconfigFlagsPbFile));
75 
76         File aconfigFlagsEmptyPbFile = testFolder.newFile();
77         parsed_flags.getDefaultInstance().writeTo(new FileOutputStream(aconfigFlagsEmptyPbFile));
78         when(mTestDevice.executeShellCommand(eq("device_config list")))
79                 .thenReturn(DEVICE_CONFIG_LIST);
80         when(mTestDevice.getSerialNumber()).thenReturn("123456");
81         when(mTestDevice.doesFileExist("/system/etc/aconfig_flags.pb")).thenReturn(true);
82         when(mTestDevice.doesFileExist("/product/etc/aconfig_flags.pb")).thenReturn(true);
83         when(mTestDevice.doesFileExist("/system_ext/etc/aconfig_flags.pb")).thenReturn(false);
84         when(mTestDevice.doesFileExist("/vendor/etc/aconfig_flags.pb")).thenReturn(false);
85         when(mTestDevice.pullFile("/system/etc/aconfig_flags.pb")).thenReturn(aconfigFlagsPbFile);
86         when(mTestDevice.pullFile("/product/etc/aconfig_flags.pb"))
87                 .thenReturn(aconfigFlagsEmptyPbFile);
88         mHostFlagsValueProvider =
89                 new HostFlagsValueProvider(
90                         () -> {
91                             return mTestDevice;
92                         });
93         mHostFlagsValueProvider.setUp();
94     }
95 
96     @Test
getBoolean_flagNotExist_throwException()97     public void getBoolean_flagNotExist_throwException() throws Exception {
98         assertThrows(
99                 FlagReadException.class,
100                 () -> mHostFlagsValueProvider.getBoolean("flag_not_exist"));
101     }
102 
103     @Test
getBoolean_flagNotBoolean_throwException()104     public void getBoolean_flagNotBoolean_throwException() throws Exception {
105         assertThrows(
106                 FlagReadException.class,
107                 () -> mHostFlagsValueProvider.getBoolean("namespace2/flag1"));
108     }
109 
110     @Test
getBoolean_verify()111     public void getBoolean_verify() throws Exception {
112         assertTrue(mHostFlagsValueProvider.getBoolean("namespace1/flag1"));
113         assertFalse(mHostFlagsValueProvider.getBoolean("namespace1/flag2"));
114         assertFalse(mHostFlagsValueProvider.getBoolean("cts/com.android.flags.my_flag"));
115     }
116 
117     @Test
getBoolean_afterRefresh()118     public void getBoolean_afterRefresh() throws Exception {
119         when(mTestDevice.executeShellCommand(eq("device_config list")))
120                 .thenReturn("namespace1/flag1=false");
121         HostFlagsValueProvider.refreshFlagsCache("123456");
122 
123         assertFalse(mHostFlagsValueProvider.getBoolean("namespace1/flag1"));
124     }
125 
126     @Test
isBoolean_verify()127     public void isBoolean_verify() {
128         assertTrue(IFlagsValueProvider.isBooleanValue("true"));
129         assertTrue(IFlagsValueProvider.isBooleanValue("false"));
130         assertFalse(IFlagsValueProvider.isBooleanValue("True"));
131         assertFalse(IFlagsValueProvider.isBooleanValue("False"));
132         assertFalse(IFlagsValueProvider.isBooleanValue(""));
133         assertFalse(IFlagsValueProvider.isBooleanValue("abc"));
134     }
135 }
136