• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.tests.fastboot_getvar;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22 
23 import com.android.tradefed.device.ITestDevice;
24 import com.android.tradefed.device.TestDeviceState;
25 import com.android.tradefed.invoker.TestInformation;
26 import com.android.tradefed.log.LogUtil.CLog;
27 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
28 import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
29 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
30 import com.android.tradefed.util.AbiFormatter;
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashSet;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import org.junit.Assert;
39 import org.junit.Assume;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 /* VTS test to verify userspace fastboot getvar information. */
45 @RunWith(DeviceJUnit4ClassRunner.class)
46 public class FastbootGetvarUserspaceTest extends BaseHostJUnit4Test {
47     private static final int PLATFORM_API_LEVEL_R = 30;
48     private static final int ANDROID_RELEASE_VERSION_R = 11;
49 
50     private ITestDevice mDevice;
51 
52     @Before
setUp()53     public void setUp() throws Exception {
54         mDevice = getDevice();
55 
56         ArrayList<String> supportedAbis = new ArrayList<>(Arrays.asList(AbiFormatter.getSupportedAbis(mDevice, "")));
57         if (supportedAbis.contains("arm64-v8a")) {
58             String output = mDevice.executeShellCommand("uname -r");
59             Pattern p = Pattern.compile("^(\\d+)\\.(\\d+)");
60             Matcher m1 = p.matcher(output);
61             Assert.assertTrue(m1.find());
62             Assume.assumeTrue("Skipping test for fastbootd on GKI",
63                               Integer.parseInt(m1.group(1)) < 5 ||
64                               (Integer.parseInt(m1.group(1)) == 5 &&
65                                Integer.parseInt(m1.group(2)) < 4));
66         }
67 
68         // Make sure the device is in fastbootd mode.
69         if (!TestDeviceState.FASTBOOT.equals(mDevice.getDeviceState())) {
70             mDevice.rebootIntoFastbootd();
71         }
72     }
73 
74     @AfterClassWithInfo
tearDownClass(TestInformation testInfo)75     public static void tearDownClass(TestInformation testInfo) throws Exception {
76         testInfo.getDevice().reboot();
77     }
78 
79     /* Devices launching in R and after must export cpu-abi. */
80     @Test
testCpuAbiInfo()81     public void testCpuAbiInfo() throws Exception {
82         final HashSet<String> allCpuAbis = new HashSet<String>(
83                 Arrays.asList("armeabi-v7a", "arm64-v8a", "mips", "mips64", "x86", "x86_64"));
84         String cpuAbi = mDevice.getFastbootVariable("cpu-abi");
85         CLog.d("cpuAbi: '%s'", cpuAbi);
86         assertTrue(allCpuAbis.contains(cpuAbi));
87     }
88 
89     /* Devices launching in R and after must export version-os. */
90     @Test
testOsVersion()91     public void testOsVersion() throws Exception {
92         String osVersion = mDevice.getFastbootVariable("version-os");
93         CLog.d("os version: '%s'", osVersion);
94         // The value of osVersion might be a letter on pre-release builds, e.g., R,
95         // or is a number representing the Android release version, e.g., 11.
96         try {
97             int intOsVersion = Integer.parseInt(osVersion);
98             assertTrue(intOsVersion >= ANDROID_RELEASE_VERSION_R);
99         } catch (NumberFormatException nfe) {
100             assertTrue(osVersion.matches("[A-Z]+"));
101         }
102     }
103 
104     /* Devices launching in R and after must export version-vndk. */
105     @Test
testVndkVersion()106     public void testVndkVersion() throws Exception {
107         String vndkVersion = mDevice.getFastbootVariable("version-vndk");
108         CLog.d("vndk version: '%s'", vndkVersion);
109         // The value of vndkVersion might be a letter on pre-release builds, e.g., R,
110         // or is a number representing the API level on final release builds, e.g., 30.
111         try {
112             int intVndkVersion = Integer.parseInt(vndkVersion);
113             assertTrue(intVndkVersion >= PLATFORM_API_LEVEL_R);
114         } catch (NumberFormatException nfe) {
115             assertTrue(vndkVersion.matches("[A-Z]+"));
116         }
117     }
118 
119     /* Devices launching in R and after must export dynamic-partition. */
120     @Test
testDynamicPartition()121     public void testDynamicPartition() throws Exception {
122         String dynamic_partition = mDevice.getFastbootVariable("dynamic-partition");
123         CLog.d("dynamic_partition: '%s'", dynamic_partition);
124         assertTrue(dynamic_partition.equals("true"));
125     }
126 
127     /* Devices launching in R and after must export treble-enabled. */
128     @Test
testTrebleEnable()129     public void testTrebleEnable() throws Exception {
130         String treble_enabled = mDevice.getFastbootVariable("treble-enabled");
131         CLog.d("treble_enabled: '%s'", treble_enabled);
132         assertTrue(treble_enabled.equals("true") || treble_enabled.equals("false"));
133     }
134 
135     /* Devices launching in R and after must export first-api-level. */
136     @Test
testFirstApiLevel()137     public void testFirstApiLevel() throws Exception {
138         String first_api_level = mDevice.getFastbootVariable("first-api-level");
139         CLog.d("first_api_level: '%s'", first_api_level);
140         try {
141             int api_level = Integer.parseInt(first_api_level);
142             assertTrue(api_level >= PLATFORM_API_LEVEL_R);
143         } catch (NumberFormatException nfe) {
144             fail("Failed to parse first-api-level: " + first_api_level);
145         }
146     }
147 
148     /* Devices launching in R and after must export security-patch-level. */
149     @Test
testSecurityPatchLevel()150     public void testSecurityPatchLevel() throws Exception {
151         String SPL = mDevice.getFastbootVariable("security-patch-level");
152         CLog.d("SPL: '%s'", SPL);
153         try {
154             SimpleDateFormat template = new SimpleDateFormat("yyyy-MM-dd");
155             template.parse(SPL);
156         } catch (ParseException e) {
157             fail("Failed to parse security-patch-level: " + SPL);
158         }
159     }
160 
161     /* Devices launching in R and after must export system-fingerprint. */
162     @Test
testSystemFingerprint()163     public void testSystemFingerprint() throws Exception {
164         String systemFingerprint = mDevice.getFastbootVariable("system-fingerprint");
165         CLog.d("system fingerprint: '%s'", systemFingerprint);
166         verifyFingerprint(systemFingerprint);
167     }
168 
169     /* Devices launching in R and after must export vendor-fingerprint. */
170     @Test
testVendorFingerprint()171     public void testVendorFingerprint() throws Exception {
172         String vendorFingerprint = mDevice.getFastbootVariable("vendor-fingerprint");
173         CLog.d("vendor fingerprint: '%s'", vendorFingerprint);
174         verifyFingerprint(vendorFingerprint);
175     }
176 
177     /*
178      *  Verifies the fingerprint defined in CDD.
179      *    https://source.android.com/compatibility/cdd
180      *
181      *  The fingerprint should be of format:
182      *    $(BRAND)/$(PRODUCT)/$(DEVICE):$(VERSION.RELEASE)/$(ID)/$(VERSION.INCREMENTAL):$(TYPE)/$(TAGS).
183      */
verifyFingerprint(String fingerprint)184     private void verifyFingerprint(String fingerprint) {
185         final HashSet<String> allBuildVariants =
186                 new HashSet<String>(Arrays.asList("user", "userdebug", "eng"));
187 
188         final HashSet<String> allTags =
189                 new HashSet<String>(Arrays.asList("release-keys", "dev-keys", "test-keys"));
190 
191         verifyFingerprintStructure(fingerprint);
192 
193         String[] fingerprintSegs = fingerprint.split("/");
194         assertTrue(fingerprintSegs[0].matches("^[a-zA-Z0-9_-]+$")); // BRAND
195         assertTrue(fingerprintSegs[1].matches("^[a-zA-Z0-9_-]+$")); // PRODUCT
196 
197         String[] devicePlatform = fingerprintSegs[2].split(":");
198         assertEquals(2, devicePlatform.length);
199         assertTrue(devicePlatform[0].matches("^[a-zA-Z0-9_-]+$")); // DEVICE
200 
201         // Platform version is a letter on pre-release builds, e.g., R, or
202         // is a number on final release # builds, e.g., 11.
203         try {
204             int releaseVersion = Integer.parseInt(devicePlatform[1]); // VERSION.RELEASE
205             assertTrue(releaseVersion >= ANDROID_RELEASE_VERSION_R);
206         } catch (NumberFormatException nfe) {
207             assertTrue(devicePlatform[1].matches("[A-Z]+"));
208         }
209 
210         assertTrue(fingerprintSegs[3].matches("^[a-zA-Z0-9._-]+$")); // ID
211 
212         String[] buildNumberVariant = fingerprintSegs[4].split(":");
213         assertTrue(buildNumberVariant[0].matches("^[^ :\\/~]+$")); // VERSION.INCREMENTAL
214         assertTrue(allBuildVariants.contains(buildNumberVariant[1])); // TYPE
215 
216         assertTrue(allTags.contains(fingerprintSegs[5])); // TAG
217     }
218 
verifyFingerprintStructure(String fingerprint)219     private void verifyFingerprintStructure(String fingerprint) {
220         assertEquals("Build fingerprint must not include whitespace", -1, fingerprint.indexOf(' '));
221 
222         String[] segments = fingerprint.split("/");
223         assertEquals("Build fingerprint does not match expected format", 6, segments.length);
224 
225         String[] devicePlatform = segments[2].split(":");
226         assertEquals(2, devicePlatform.length);
227 
228         assertTrue(segments[4].contains(":"));
229         String buildVariant = segments[4].split(":")[1];
230         assertTrue(buildVariant.length() > 0);
231     }
232 }
233