1 /*
2  * Copyright (C) 2019 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.rollback.host;
18 
19 import static org.junit.Assert.assertTrue;
20 
21 import com.android.ddmlib.Log.LogLevel;
22 import com.android.tradefed.log.LogUtil.CLog;
23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
24 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
25 
26 import org.junit.After;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 /**
32  * Runs the staged rollback tests.
33  */
34 @RunWith(DeviceJUnit4ClassRunner.class)
35 public class StagedRollbackTest extends BaseHostJUnit4Test {
36     /**
37      * Runs the given phase of a test by calling into the device.
38      * Throws an exception if the test phase fails.
39      * <p>
40      * For example, <code>runPhase("testApkOnlyEnableRollback");</code>
41      */
runPhase(String phase)42     private void runPhase(String phase) throws Exception {
43         assertTrue(runDeviceTests("com.android.tests.rollback",
44                     "com.android.tests.rollback.StagedRollbackTest",
45                     phase));
46     }
47 
48     @Before
setUp()49     public void setUp() throws Exception {
50         // Disconnect internet so we can test network health triggered rollbacks
51         getDevice().executeShellCommand("svc wifi disable");
52         getDevice().executeShellCommand("svc data disable");
53     }
54 
55     @After
tearDown()56     public void tearDown() throws Exception {
57         // Reconnect internet after testing network health triggered rollbacks
58         getDevice().executeShellCommand("svc wifi enable");
59         getDevice().executeShellCommand("svc data enable");
60     }
61 
62     /**
63      * Tests watchdog triggered staged rollbacks involving only apks.
64      */
65     @Test
testBadApkOnly()66     public void testBadApkOnly() throws Exception {
67         runPhase("testBadApkOnlyEnableRollback");
68         getDevice().reboot();
69         runPhase("testBadApkOnlyConfirmEnableRollback");
70         try {
71             // This is expected to fail due to the device being rebooted out
72             // from underneath the test. If this fails for reasons other than
73             // the device reboot, those failures should result in failure of
74             // the testApkOnlyConfirmRollback phase.
75             CLog.logAndDisplay(LogLevel.INFO, "testBadApkOnlyTriggerRollback is expected to fail");
76             runPhase("testBadApkOnlyTriggerRollback");
77         } catch (AssertionError e) {
78             // AssertionError is expected.
79         }
80 
81         getDevice().waitForDeviceAvailable();
82 
83         runPhase("testBadApkOnlyConfirmRollback");
84     }
85 
86     /**
87      * Tests failed network health check triggers watchdog staged rollbacks.
88      */
89     @Test
testNetworkFailedRollback()90     public void testNetworkFailedRollback() throws Exception {
91         // Remove available rollbacks and uninstall NetworkStack on /data/
92         runPhase("resetNetworkStack");
93         // Reduce health check deadline
94         getDevice().executeShellCommand("device_config put rollback "
95                 + "watchdog_request_timeout_millis 300000");
96         // Simulate re-installation of new NetworkStack with rollbacks enabled
97         getDevice().executeShellCommand("pm install -r --staged --enable-rollback "
98                 + "/system/priv-app/NetworkStack/NetworkStack.apk");
99 
100         // Sleep to allow writes to disk before reboot
101         Thread.sleep(5000);
102         // Reboot device to activate staged package
103         getDevice().reboot();
104         getDevice().waitForDeviceAvailable();
105 
106         // Verify rollback was enabled
107         runPhase("assertNetworkStackRollbackAvailable");
108 
109         // Sleep for < health check deadline
110         Thread.sleep(5000);
111         // Verify rollback was not executed before health check deadline
112         runPhase("assertNoNetworkStackRollbackCommitted");
113         try {
114             // This is expected to fail due to the device being rebooted out
115             // from underneath the test. If this fails for reasons other than
116             // the device reboot, those failures should result in failure of
117             // the assertNetworkStackExecutedRollback phase.
118             CLog.logAndDisplay(LogLevel.INFO, "Sleep and expect to fail while sleeping");
119             // Sleep for > health check deadline
120             Thread.sleep(260000);
121         } catch (AssertionError e) {
122             // AssertionError is expected.
123         }
124 
125         getDevice().waitForDeviceAvailable();
126         // Verify rollback was executed after health check deadline
127         runPhase("assertNetworkStackRollbackCommitted");
128     }
129 
130     /**
131      * Tests passed network health check does not trigger watchdog staged rollbacks.
132      */
133     @Test
testNetworkPassedDoesNotRollback()134     public void testNetworkPassedDoesNotRollback() throws Exception {
135         // Remove available rollbacks and uninstall NetworkStack on /data/
136         runPhase("resetNetworkStack");
137         // Reduce health check deadline, here unlike the network failed case, we use
138         // a longer deadline because joining a network can take a much longer time for
139         // reasons external to the device than 'not joining'
140         getDevice().executeShellCommand("device_config put rollback "
141                 + "watchdog_request_timeout_millis 300000");
142         // Simulate re-installation of new NetworkStack with rollbacks enabled
143         getDevice().executeShellCommand("pm install -r --staged --enable-rollback "
144                 + "/system/priv-app/NetworkStack/NetworkStack.apk");
145 
146         // Sleep to allow writes to disk before reboot
147         Thread.sleep(5000);
148         // Reboot device to activate staged package
149         getDevice().reboot();
150         getDevice().waitForDeviceAvailable();
151 
152         // Verify rollback was enabled
153         runPhase("assertNetworkStackRollbackAvailable");
154 
155         // Connect to internet so network health check passes
156         getDevice().executeShellCommand("svc wifi enable");
157         getDevice().executeShellCommand("svc data enable");
158 
159         // Wait for device available because emulator device may restart after turning
160         // on mobile data
161         getDevice().waitForDeviceAvailable();
162 
163         // Sleep for > health check deadline
164         Thread.sleep(310000);
165         // Verify rollback was not executed after health check deadline
166         runPhase("assertNoNetworkStackRollbackCommitted");
167     }
168 }
169