blob: fc6be6f3a7d21d5f6b34d68a8994b0017c1791cd [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.cts.install.host;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.cts.install.INSTALL_TYPE;
import android.platform.test.annotations.LargeTest;
import com.android.compatibility.common.util.CpuFeatures;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@RunWith(DeviceParameterized.class)
@UseParametersRunnerFactory(DeviceParameterized.RunnerFactory.class)
public final class DowngradeTest extends BaseHostJUnit4Test {
private static final String PACKAGE_NAME = "android.cts.install";
private static final String PHASE_FORMAT_SUFFIX = "[%s_Staged%b_Rollback%b]";
private static final String CLEAN_UP_PHASE = "cleanUp_phase";
private static final String ARRANGE_PHASE = "arrange_phase";
private static final String ASSERT_POST_ARRANGE_PHASE = "assert_postArrange_phase";
private static final String ACTION_PHASE = "action_phase";
private static final String ASSERT_DOWNGRADE_SUCCESS_PHASE = "assert_downgradeSuccess_phase";
private static final String ASSERT_POST_REBOOT_PHASE = "assert_postReboot_phase";
private static final String ASSERT_PRE_REBOOT_PHASE = "assert_preReboot_phase";
private static final String ASSERT_DOWNGRADE_NOT_ALLOWED_PHASE =
"assert_downgradeNotAllowed_phase";
private static final String ASSERT_DOWNGRADE_NOT_REQUESTED_PHASE =
"assert_downgradeNotRequested_phase";
@Rule
public ShimApexRule mShimApexRule = new ShimApexRule(this);
@Parameter(0)
public INSTALL_TYPE mInstallType;
@Parameter(1)
public boolean mEnableRollback;
@Parameters(name = "{0}_Rollback{1}")
public static Collection<Object[]> combinations() {
boolean[] booleanValues = new boolean[]{true, false};
List<Object[]> temp = new ArrayList<>();
for (INSTALL_TYPE installType : INSTALL_TYPE.values()) {
for (boolean enableRollback : booleanValues) {
temp.add(new Object[]{installType, enableRollback});
}
}
return temp;
}
@Before
@After
public void cleanUp() throws Exception {
runPhase(CLEAN_UP_PHASE);
}
@Before
public void assumeApexSupported() throws DeviceNotAvailableException {
if (mInstallType.containsApex()) {
assumeTrue("Device does not support updating APEX",
mShimApexRule.isUpdatingApexSupported());
}
}
@Before
public void assumeNotNativeBridgeWithApex() throws Exception {
if (!CpuFeatures.isNativeAbi(getDevice(), getAbi().getName())) {
assumeFalse("APEX packages do not work with native bridge",
mInstallType.containsApex());
}
}
@Test
public void testNonStagedDowngrade_downgradeNotRequested_fails() throws Exception {
// Apex should not be committed in non-staged install, such logic covered in InstallTest.
assumeFalse(mInstallType.containsApex());
runPhase(ARRANGE_PHASE);
runPhase(ASSERT_POST_ARRANGE_PHASE);
runPhase(ASSERT_DOWNGRADE_NOT_REQUESTED_PHASE);
}
@Test
public void testNonStagedDowngrade_debugBuild() throws Exception {
// Apex should not be committed in non-staged install, such logic covered in InstallTest.
assumeFalse(mInstallType.containsApex());
assumeTrue("Device is not debuggable", isDebuggable());
runPhase(ARRANGE_PHASE);
runPhase(ASSERT_POST_ARRANGE_PHASE);
runPhase(ACTION_PHASE);
runPhase(ASSERT_DOWNGRADE_SUCCESS_PHASE);
}
@Test
public void testNonStagedDowngrade_nonDebugBuild_fail() throws Exception {
// Apex should not be committed in non-staged install, such logic covered in InstallTest.
assumeFalse(mInstallType.containsApex());
assumeFalse("Device is debuggable", isDebuggable());
runPhase(ARRANGE_PHASE);
runPhase(ASSERT_POST_ARRANGE_PHASE);
runPhase(ASSERT_DOWNGRADE_NOT_ALLOWED_PHASE);
}
@Test
@LargeTest
public void testStagedDowngrade_downgradeNotRequested_fails() throws Exception {
runStagedPhase(ARRANGE_PHASE);
getDevice().reboot();
runStagedPhase(ASSERT_POST_ARRANGE_PHASE);
runStagedPhase(ASSERT_DOWNGRADE_NOT_REQUESTED_PHASE);
}
@Test
@LargeTest
public void testStagedDowngrade_debugBuild() throws Exception {
assumeTrue("Device is not debuggable", isDebuggable());
runStagedPhase(ARRANGE_PHASE);
getDevice().reboot();
runStagedPhase(ASSERT_POST_ARRANGE_PHASE);
runStagedPhase(ACTION_PHASE);
runStagedPhase(ASSERT_PRE_REBOOT_PHASE);
getDevice().reboot();
runStagedPhase(ASSERT_POST_REBOOT_PHASE);
}
@Test
@LargeTest
public void testStagedDowngrade_nonDebugBuild_fail() throws Exception {
assumeFalse("Device is debuggable", isDebuggable());
runStagedPhase(ARRANGE_PHASE);
getDevice().reboot();
runStagedPhase(ASSERT_POST_ARRANGE_PHASE);
runStagedPhase(ASSERT_DOWNGRADE_NOT_ALLOWED_PHASE);
}
private void runPhase(String phase) throws DeviceNotAvailableException {
runPhase(phase, false /* staged */);
}
private void runStagedPhase(String phase) throws DeviceNotAvailableException {
runPhase(phase, true /* staged */);
}
/**
* Runs the given phase of a test with parameters by calling into the device.
* Throws an exception if the test phase fails.
* <p>
* For example, <code>runPhase("action_phase", true);</code>
*/
private void runPhase(String phase, boolean staged) throws DeviceNotAvailableException {
assertThat(runDeviceTests(PACKAGE_NAME,
String.format("%s.%s", PACKAGE_NAME, this.getClass().getSimpleName()),
String.format(phase + PHASE_FORMAT_SUFFIX, mInstallType, staged, mEnableRollback)))
.isTrue();
}
private boolean isDebuggable() throws Exception {
return getDevice().getIntProperty("ro.debuggable", 0) == 1;
}
}