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.apex;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.cts.install.lib.host.InstallUtilsHost;
24 
25 import com.android.compatibility.common.util.CpuFeatures;
26 import com.android.internal.util.test.SystemPreparer;
27 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
28 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
29 
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.RuleChain;
33 import org.junit.rules.TemporaryFolder;
34 import org.junit.runner.RunWith;
35 
36 
37 @RunWith(DeviceJUnit4ClassRunner.class)
38 public class SharedLibsApexTest extends BaseHostJUnit4Test {
39 
40     private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
41     private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
42     private final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder,
43             this::getDevice);
44 
45     @Rule
46     public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer);
47 
48     enum ApexName {
49         FOO,
50         BAR,
51         BAZ,
52         PONY,
53         SHAREDLIBS,
54         SHAREDLIBS_SECONDARY
55     }
56 
57     enum ApexVersion {
58         ONE,
59         TWO
60     }
61 
62     enum ApexType {
63         DEFAULT,
64         STRIPPED
65     }
66 
67     enum SharedLibsVersion {
68         X,
69         Y,
70         Z
71     }
72 
73     /**
74      * Utility function to generate test apex names in the form e.g.:
75      *   "com.android.apex.test.bar.v1.libvX.apex"
76      */
getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion, SharedLibsVersion sharedLibsVersion)77     private String getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion,
78             SharedLibsVersion sharedLibsVersion) {
79         StringBuilder ret = new StringBuilder();
80         ret.append("com.android.apex.test.");
81         switch(apexName) {
82             case FOO:
83                 ret.append("foo");
84                 break;
85             case BAR:
86                 ret.append("bar");
87                 break;
88             case BAZ:
89                 ret.append("baz");
90                 break;
91             case PONY:
92                 ret.append("pony");
93                 break;
94             case SHAREDLIBS:
95                 ret.append("sharedlibs_generated");
96                 break;
97             case SHAREDLIBS_SECONDARY:
98                 ret.append("sharedlibs_secondary_generated");
99                 break;
100         }
101 
102         switch(apexType) {
103             case STRIPPED:
104                 ret.append("_stripped");
105                 break;
106             case DEFAULT:
107                 break;
108         }
109 
110         switch(apexVersion) {
111             case ONE:
112                 ret.append(".v1");
113                 break;
114             case TWO:
115                 ret.append(".v2");
116                 break;
117         }
118 
119         switch(sharedLibsVersion) {
120             case X:
121                 ret.append(".libvX.apex");
122                 break;
123             case Y:
124                 ret.append(".libvY.apex");
125                 break;
126             case Z:
127                 ret.append(".libvZ.apex");
128                 break;
129         }
130 
131         return ret.toString();
132     }
133 
134     /**
135      * Utility function to generate the file name of an installed package as per
136      * apexd convention e.g.: "com.android.apex.test.bar@1.apex"
137      */
getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion)138     private String getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion) {
139         StringBuilder ret = new StringBuilder();
140         ret.append("com.android.apex.test.");
141         switch(apexName) {
142             case FOO:
143                 ret.append("foo");
144                 break;
145             case BAR:
146                 ret.append("bar");
147                 break;
148             case BAZ:
149                 ret.append("baz");
150                 break;
151             case PONY:
152                 ret.append("pony");
153                 break;
154             case SHAREDLIBS:
155                 ret.append("sharedlibs");
156                 break;
157             case SHAREDLIBS_SECONDARY:
158                 ret.append("sharedlibs_secondary");
159                 break;
160         }
161         ret.append("@");
162         switch(apexVersion) {
163             case ONE:
164                 ret.append("1");
165                 break;
166             case TWO:
167                 ret.append("2");
168                 break;
169         }
170         ret.append(".apex");
171         return ret.toString();
172     }
173 
174     /**
175      * Tests basic functionality of two apex packages being force-installed and the C++ binaries
176      * contained in them being executed correctly.
177      */
178     @Test
testInstallAndRunDefaultApexs()179     public void testInstallAndRunDefaultApexs() throws Exception {
180         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
181         assumeTrue("Device requires root", getDevice().isAdbRoot());
182 
183         for (String apex : new String[]{
184                 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X),
185                 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X),
186                 getTestApex(ApexName.PONY, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.Z),
187         }) {
188             mPreparer.pushResourceFile(apex,
189                     "/system/apex/" + apex);
190         }
191         mPreparer.reboot();
192 
193         getDevice().disableAdbRoot();
194         String runAsResult = getDevice().executeShellCommand(
195                 "/apex/com.android.apex.test.foo/bin/foo_test");
196         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
197         runAsResult = getDevice().executeShellCommand(
198                 "/apex/com.android.apex.test.bar/bin/bar_test32");
199         assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
200         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
201             runAsResult = getDevice().executeShellCommand(
202                     "/apex/com.android.apex.test.bar/bin/bar_test64");
203             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
204         }
205         runAsResult = getDevice().executeShellCommand(
206                 "/apex/com.android.apex.test.pony/bin/pony_test");
207         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
208 
209         mPreparer.stageMultiplePackages(
210             new String[]{
211                 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y),
212                 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y),
213             },
214             new String[] {
215                 "com.android.apex.test.bar",
216                 "com.android.apex.test.foo",
217             }).reboot();
218 
219         runAsResult = getDevice().executeShellCommand(
220             "/apex/com.android.apex.test.foo/bin/foo_test");
221         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
222         runAsResult = getDevice().executeShellCommand(
223             "/apex/com.android.apex.test.bar/bin/bar_test32");
224         assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
225         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
226             runAsResult = getDevice().executeShellCommand(
227                 "/apex/com.android.apex.test.bar/bin/bar_test64");
228             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
229         }
230     }
231 
232     /**
233      * Tests functionality of shared libraries apex: installs two apexs "stripped" of libc++.so and
234      * one apex containing it and verifies that C++ binaries can run.
235      */
236     @Test
testInstallAndRunOptimizedApexs()237     public void testInstallAndRunOptimizedApexs() throws Exception {
238         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
239         assumeTrue("Device requires root", getDevice().isAdbRoot());
240 
241         // Base case:
242         //
243         // Pre-installed on /system:
244         //   package bar version 1 using library version X
245         //   package foo version 1 using library version X
246         //   package sharedlibs version 1 exporting library version X
247         //
248         //   package pony version 1 using library version Z
249         //   package sharedlibs_secondary version 1 exporting library version Z
250 
251         for (String apex : new String[]{
252                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
253                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
254                 getTestApex(ApexName.PONY, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.Z),
255                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
256                     SharedLibsVersion.X),
257                 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE,
258                     SharedLibsVersion.Z),
259         }) {
260             mPreparer.pushResourceFile(apex,
261                     "/system/apex/" + apex);
262         }
263         mPreparer.reboot();
264 
265         getDevice().disableAdbRoot();
266         String runAsResult = getDevice().executeShellCommand(
267                 "/apex/com.android.apex.test.foo/bin/foo_test");
268         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
269         runAsResult = getDevice().executeShellCommand(
270                 "/apex/com.android.apex.test.bar/bin/bar_test32");
271         assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
272         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
273             runAsResult = getDevice().executeShellCommand(
274                     "/apex/com.android.apex.test.bar/bin/bar_test64");
275             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
276         }
277         runAsResult = getDevice().executeShellCommand(
278                 "/apex/com.android.apex.test.pony/bin/pony_test");
279         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
280 
281         // Edge case: sharedlibs updated with a same version apex.
282         //
283         // Updated packages (installed on /data/apex/active):
284         //   package sharedlibs version 1 exporting library version X            <-- new
285         //   package sharedlibs_secondary version 1 exporting library version Z  <-- new
286         //
287         // Pre-installed:
288         //   package bar version 1 using library version X
289         //   package foo version 1 using library version X
290         //   (inactive) package sharedlibs version 1 exporting library version X
291         //
292         //   package pony version 1 using library version Z
293         //   (inactive) package sharedlibs_secondary version 1 exporting library version Z
294 
295         mPreparer.stageMultiplePackages(
296             new String[]{
297                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
298                     SharedLibsVersion.X),
299                 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE,
300                     SharedLibsVersion.Z),
301             },
302             new String[]{
303                 "com.android.apex.test.sharedlibs",
304                 "com.android.apex.test.sharedlibs_secondary",
305             }).reboot();
306 
307         runAsResult = getDevice().executeShellCommand(
308                 "/apex/com.android.apex.test.foo/bin/foo_test");
309         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
310         runAsResult = getDevice().executeShellCommand(
311                 "/apex/com.android.apex.test.bar/bin/bar_test32");
312         assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
313         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
314             runAsResult = getDevice().executeShellCommand(
315                     "/apex/com.android.apex.test.bar/bin/bar_test64");
316             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
317         }
318         runAsResult = getDevice().executeShellCommand(
319                 "/apex/com.android.apex.test.pony/bin/pony_test");
320         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
321 
322         // Updated packages (installed on /data/apex/active):
323         //   package bar version 2 using library version Y               <-- new
324         //   package foo version 2 using library version Y               <-- new
325         //   package sharedlibs version 2 exporting library version Y    <-- new
326         //   package sharedlibs_secondary version 1 exporting library version Z
327         //
328         // Pre-installed:
329         //   (inactive) package bar version 1 using library version X
330         //   (inactive) package foo version 1 using library version X
331         //   package sharedlibs version 1 exporting library version X
332         //
333         //   package pony version 1 using library version Z
334         //   (inactive) package sharedlibs_secondary version 1 exporting library version Z
335 
336         mPreparer.stageMultiplePackages(
337             new String[]{
338                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
339                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
340                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO,
341                     SharedLibsVersion.Y),
342             },
343             new String[]{
344                 "com.android.apex.test.bar",
345                 "com.android.apex.test.foo",
346                 "com.android.apex.test.sharedlibs",
347             }).reboot();
348 
349         runAsResult = getDevice().executeShellCommand(
350             "/apex/com.android.apex.test.foo/bin/foo_test");
351         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
352         runAsResult = getDevice().executeShellCommand(
353             "/apex/com.android.apex.test.bar/bin/bar_test32");
354         assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
355         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
356             runAsResult = getDevice().executeShellCommand(
357                 "/apex/com.android.apex.test.bar/bin/bar_test64");
358             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
359         }
360         runAsResult = getDevice().executeShellCommand(
361             "/apex/com.android.apex.test.pony/bin/pony_test");
362         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
363 
364         // Assume that an OTA now adds a package baz on /system needing libraries installed on
365         // /system:
366         //
367         // Updated packages (installed on /data/apex/active):
368         //   package bar version 2 using library version Y
369         //   package foo version 2 using library version Y
370         //   package sharedlibs version 2 exporting library version Y
371         //
372         // Pre-installed:
373         //   (inactive) package bar version 1 using library version X
374         //   package baz version 1 using library version X               <-- new
375         //   (inactive) package foo version 1 using library version X
376         //   package sharedlibs version 1 exporting library version X
377         //   package pony version 1 using library version Z
378         //   package sharedlibs_secondary version 1 exporting library version Z
379 
380         String baz_apex =
381                 getTestApex(ApexName.BAZ, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X);
382         mPreparer.pushResourceFile(baz_apex, "/system/apex/" + baz_apex);
383         mPreparer.reboot();
384 
385         runAsResult = getDevice().executeShellCommand(
386             "/apex/com.android.apex.test.foo/bin/foo_test");
387         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
388         runAsResult = getDevice().executeShellCommand(
389             "/apex/com.android.apex.test.bar/bin/bar_test32");
390         assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
391         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
392             runAsResult = getDevice().executeShellCommand(
393                 "/apex/com.android.apex.test.bar/bin/bar_test64");
394             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
395         }
396         runAsResult = getDevice().executeShellCommand(
397             "/apex/com.android.apex.test.baz/bin/baz_test");
398         assertThat(runAsResult).isEqualTo("BAZ_VERSION_1 SHARED_LIB_VERSION_X");
399         runAsResult = getDevice().executeShellCommand(
400                 "/apex/com.android.apex.test.pony/bin/pony_test");
401         assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z");
402     }
403 
404     /**
405      * Tests that when a shared library apex is updated via OTA the previously
406      * downloaded version is remoted.
407      */
408     @Test
testHigherVersionOnSystemDeletesDataVersion()409     public void testHigherVersionOnSystemDeletesDataVersion() throws Exception {
410         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
411         assumeTrue("Device requires root", getDevice().isAdbRoot());
412 
413         // Base case:
414         //
415         // Pre-installed on /system:
416         //   package bar version 1 using library version X
417         //   package foo version 1 using library version X
418         //   package sharedlibs version 1 exporting library version X
419         for (String apex : new String[]{
420                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
421                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
422                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
423                     SharedLibsVersion.X),
424         }) {
425             mPreparer.pushResourceFile(apex,
426                     "/system/apex/" + apex);
427         }
428         mPreparer.reboot();
429         String runAsResult = getDevice().executeShellCommand(
430                 "/apex/com.android.apex.test.foo/bin/foo_test");
431         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
432         runAsResult = getDevice().executeShellCommand(
433                 "/apex/com.android.apex.test.bar/bin/bar_test32");
434         assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
435         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
436             runAsResult = getDevice().executeShellCommand(
437                     "/apex/com.android.apex.test.bar/bin/bar_test64");
438             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
439         }
440 
441         // Same-grade case:
442         //
443         // Pre-installed on /system:
444         //   package bar version 1 using library version X
445         //   package foo version 1 using library version X
446         //   package sharedlibs version 1 exporting library version X
447         // Updated packages (installed on /data/apex/active):
448         //   package bar version 1 using library version X
449         //   package foo version 1 using library version X
450         //   package sharedlibs version 1 exporting library version X
451         mPreparer.stageMultiplePackages(
452             new String[]{
453                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
454                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
455                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
456                     SharedLibsVersion.X),
457             },
458             new String[]{
459                 "com.android.apex.test.bar",
460                 "com.android.apex.test.foo",
461                 "com.android.apex.test.sharedlibs",
462             }).reboot();
463 
464         runAsResult = getDevice().executeShellCommand(
465                 "/apex/com.android.apex.test.foo/bin/foo_test");
466         assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X");
467         runAsResult = getDevice().executeShellCommand(
468                 "/apex/com.android.apex.test.bar/bin/bar_test32");
469         assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
470         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
471             runAsResult = getDevice().executeShellCommand(
472                     "/apex/com.android.apex.test.bar/bin/bar_test64");
473             assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X");
474         }
475 
476         // Simulate OTA upgrading pre-installed modules:
477         //
478         // Pre-installed on /system:
479         //   package bar version 2 using library version Y
480         //   package foo version 2 using library version Y
481         //   package sharedlibs version 2 exporting library version Y
482         //
483         // Updated packages (installed on /data/apex/active):
484         //   package bar version 1 using library version X (deleted)
485         //   package foo version 1 using library version X (deleted)
486         //   package sharedlibs version 1 exporting library version X (deleted)
487         //
488         for (String apex : new String[]{
489                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
490                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X),
491                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE,
492                     SharedLibsVersion.X),
493         }) {
494             mPreparer.deleteFile("/system/apex/" + apex);
495         }
496         for (String apex : new String[]{
497                 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
498                 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y),
499                 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO,
500                     SharedLibsVersion.Y),
501         }) {
502             mPreparer.pushResourceFile(apex,
503                     "/system/apex/" + apex);
504         }
505 
506         // Check that files in /data are deleted on first boot.
507         assertThat(getDevice().doesFileExist("/data/apex/active/"
508                 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE))).isTrue();
509         assertThat(getDevice().doesFileExist("/data/apex/active/"
510                 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE))).isTrue();
511         assertThat(getDevice().doesFileExist("/data/apex/active/"
512                 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isTrue();
513         mPreparer.reboot();
514         assertThat(getDevice().doesFileExist("/data/apex/active/"
515                 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE))).isFalse();
516         assertThat(getDevice().doesFileExist("/data/apex/active/"
517                 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE))).isFalse();
518         assertThat(getDevice().doesFileExist("/data/apex/active/"
519                 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isFalse();
520 
521         getDevice().disableAdbRoot();
522         runAsResult = getDevice().executeShellCommand(
523             "/apex/com.android.apex.test.foo/bin/foo_test");
524         assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y");
525         runAsResult = getDevice().executeShellCommand(
526             "/apex/com.android.apex.test.bar/bin/bar_test32");
527         assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
528         if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) {
529             runAsResult = getDevice().executeShellCommand(
530                 "/apex/com.android.apex.test.bar/bin/bar_test64");
531             assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y");
532         }
533     }
534 }
535