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 SamegradeTest 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 ACTION_SYSTEMAPEX_PHASE = "action_systemApex_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 ASSERT_SYSTEMAPEX_REBOOT_PHASE =
56             "assert_systemApex_postReboot_phase";
57     private static final String ASSERT_PHASE = "assert_phase";
58     private static final String CLEAN_UP_PHASE = "cleanUp_phase";
59 
60     @Rule
61     public ShimApexRule mShimApexRule = new ShimApexRule(this);
62 
63     @Parameter(0)
64     public INSTALL_TYPE mInstallType;
65 
66     @Parameter(1)
67     public boolean mEnableRollback;
68 
69     @Parameters(name = "{0}_Rollback{1}")
combinations()70     public static Collection<Object[]> combinations() {
71         boolean[] booleanValues = new boolean[]{true, false};
72         List<Object[]> temp = new ArrayList<>();
73         for (INSTALL_TYPE installType : INSTALL_TYPE.values()) {
74             for (boolean enableRollback : booleanValues) {
75                 temp.add(new Object[]{installType, enableRollback});
76             }
77         }
78         return temp;
79     }
80 
81     @Before
82     @After
cleanUp()83     public void cleanUp() throws Exception {
84         runPhase(CLEAN_UP_PHASE);
85     }
86 
87     @Before
assumeApexSupported()88     public void assumeApexSupported() throws DeviceNotAvailableException {
89         if (mInstallType.containsApex()) {
90             assumeTrue("Device does not support updating APEX",
91                     mShimApexRule.isUpdatingApexSupported());
92         }
93     }
94 
95     @Before
assumeNotNativeBridgeWithApex()96     public void assumeNotNativeBridgeWithApex() throws Exception {
97         if (!CpuFeatures.isNativeAbi(getDevice(), getAbi().getName())) {
98             assumeFalse("APEX packages do not work with native bridge",
99                     mInstallType.containsApex());
100         }
101     }
102 
103     /**
104      * Samegrading on a non-APEX install type should be success.
105      */
106     @Test
testNonStagedSamegrade()107     public void testNonStagedSamegrade() throws Exception {
108         // Apex should not be committed in non-staged install, such logic covered in InstallTest.
109         assumeFalse(mInstallType.containsApex());
110 
111         runPhase(ARRANGE_PHASE);
112         runPhase(ASSERT_POST_ARRANGE_PHASE);
113 
114         runPhase(ACTION_PHASE);
115 
116         runPhase(ASSERT_PHASE);
117     }
118 
119     @Test
120     @LargeTest
testStagedSameGrade()121     public void testStagedSameGrade() throws Exception {
122         assumeTrue(mInstallType.containsApex());
123         runStagedPhase(ARRANGE_PHASE);
124         getDevice().reboot();
125         runStagedPhase(ASSERT_POST_ARRANGE_PHASE);
126 
127         runStagedPhase(ACTION_PHASE);
128 
129         runStagedPhase(ASSERT_PRE_REBOOT_PHASE);
130         getDevice().reboot();
131         runStagedPhase(ASSERT_POST_REBOOT_PHASE);
132     }
133 
134     @Test
135     @LargeTest
testStagedSamegradeSystemApex()136     public void testStagedSamegradeSystemApex() throws Exception {
137         assumeTrue(mInstallType.containsApex());
138 
139         runStagedPhase(ACTION_SYSTEMAPEX_PHASE);
140         getDevice().reboot();
141 
142         runStagedPhase(ASSERT_SYSTEMAPEX_REBOOT_PHASE);
143     }
144 
runPhase(String phase)145     private void runPhase(String phase) throws DeviceNotAvailableException {
146         runPhase(phase, false /* staged */);
147     }
148 
runStagedPhase(String phase)149     private void runStagedPhase(String phase) throws DeviceNotAvailableException {
150         runPhase(phase, true /* staged */);
151     }
152 
153     /**
154      * Runs the given phase of a test with parameters by calling into the device.
155      * Throws an exception if the test phase fails.
156      * <p>
157      * For example, <code>runPhase("action_phase", true);</code>
158      */
runPhase(String phase, boolean staged)159     private void runPhase(String phase, boolean staged) throws DeviceNotAvailableException {
160         assertThat(runDeviceTests(PACKAGE_NAME,
161                 String.format("%s.%s", PACKAGE_NAME, this.getClass().getSimpleName()),
162                 String.format(phase + PHASE_FORMAT_SUFFIX, mInstallType, staged, mEnableRollback)))
163                 .isTrue();
164     }
165 }
166