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