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 android.cts.install.host;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.cts.install.INSTALL_TYPE;
24 import android.platform.test.annotations.LargeTest;
25 
26 import com.android.tradefed.device.DeviceNotAvailableException;
27 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
28 
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.junit.runners.Parameterized.Parameter;
35 import org.junit.runners.Parameterized.Parameters;
36 import org.junit.runners.Parameterized.UseParametersRunnerFactory;
37 
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.List;
41 
42 @RunWith(DeviceParameterized.class)
43 @UseParametersRunnerFactory(DeviceParameterized.RunnerFactory.class)
44 public final class InstallTest extends BaseHostJUnit4Test {
45     private static final String PACKAGE_NAME = "android.cts.install";
46     private static final String CUSTOMIZED_LAUNCHER_COMPONENT =
47             PACKAGE_NAME + "/" + PACKAGE_NAME + ".LauncherActivity";
48     private static final String PHASE_FORMAT_SUFFIX = "[%s_Staged%b_Rollback%b]";
49 
50     private static final String CLEAN_UP_PHASE = "cleanUp_phase";
51     private static final String ACTION_PHASE = "action_phase";
52     private static final String ACTION_ABANDON_SESSION_PHASE = "action_abandonSession_phase";
53     private static final String ASSERT_PHASE = "assert_phase";
54     private static final String ASSERT_COMMIT_FAILURE_PHASE = "assert_commitFailure_phase";
55     private static final String ASSERT_PRE_REBOOT_PHASE = "assert_preReboot_phase";
56     private static final String ASSERT_POST_REBOOT_PHASE = "assert_postReboot_phase";
57     private static final String ASSERT_ABANDON_SESSION = "assert_abandonSession_phase";
58 
59     @Rule
60     public ShimApexRule mShimApexRule = new ShimApexRule(this);
61 
62     @Rule
63     public LauncherRule mLauncherRule = new LauncherRule(this, CUSTOMIZED_LAUNCHER_COMPONENT);
64 
65     @Parameter(0)
66     public INSTALL_TYPE mInstallType;
67 
68     @Parameter(1)
69     public boolean mEnableRollback;
70 
71     @Parameters(name = "{0}_Rollback{1}")
combinations()72     public static Collection<Object[]> combinations() {
73         boolean[] booleanValues = new boolean[]{true, false};
74         List<Object[]> temp = new ArrayList<>();
75         for (INSTALL_TYPE installType: INSTALL_TYPE.values()) {
76             for (boolean enableRollback: booleanValues) {
77                 temp.add(new Object[]{installType, enableRollback});
78             }
79         }
80         return temp;
81     }
82 
83     private boolean mStaged;
84 
85     @Before
86     @After
cleanUp()87     public void cleanUp() throws Exception {
88         runPhase(CLEAN_UP_PHASE);
89     }
90 
91     @Before
assumeApexSupported()92     public void assumeApexSupported() throws DeviceNotAvailableException {
93         if (mInstallType.containsApex()) {
94             assumeTrue("Device does not support updating APEX",
95                     mShimApexRule.isUpdatingApexSupported());
96         }
97     }
98 
99     @Test
testInstall()100     public void testInstall() throws Exception {
101         mStaged = false;
102         if (mInstallType.containsApex()) {
103             runPhase(ASSERT_COMMIT_FAILURE_PHASE);
104             return;
105         }
106         runPhase(ACTION_PHASE);
107         runPhase(ASSERT_PHASE);
108     }
109 
110     @Test
111     @LargeTest
testStagedInstall()112     public void testStagedInstall() throws Exception {
113         mStaged = true;
114         runPhase(ACTION_PHASE);
115         runPhase(ASSERT_PRE_REBOOT_PHASE);
116         getDevice().reboot();
117         runPhase(ASSERT_POST_REBOOT_PHASE);
118     }
119 
120     @Test
testAbandonStagedSessionBeforeReboot()121     public void testAbandonStagedSessionBeforeReboot() throws Exception {
122         mStaged = true;
123         runPhase(ACTION_PHASE);
124         runPhase(ASSERT_PRE_REBOOT_PHASE);
125         runPhase(ACTION_ABANDON_SESSION_PHASE);
126         runPhase(ASSERT_ABANDON_SESSION);
127     }
128 
129     @Test
130     @LargeTest
testAbandonStagedSessionAfterReboot()131     public void testAbandonStagedSessionAfterReboot() throws Exception {
132         mStaged = true;
133         runPhase(ACTION_PHASE);
134         getDevice().reboot();
135         runPhase(ACTION_ABANDON_SESSION_PHASE);
136         runPhase(ASSERT_POST_REBOOT_PHASE);
137     }
138 
139     /**
140      * Runs the given phase of a test with parameters by calling into the device.
141      * Throws an exception if the test phase fails.
142      * <p>
143      * For example, <code>runPhase("action_phase");</code>
144      */
runPhase(String phase)145     private void runPhase(String phase) throws DeviceNotAvailableException {
146         assertThat(runDeviceTests(PACKAGE_NAME,
147                 String.format("%s.%s", PACKAGE_NAME, this.getClass().getSimpleName()),
148                 String.format(phase + PHASE_FORMAT_SUFFIX, mInstallType, mStaged, mEnableRollback)))
149                 .isTrue();
150     }
151 }
152