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