blob: 73fbbd7ca6f8a265a9abced420e554b9b43512e3 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2018 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.
#
from vts.runners.host import asserts
from vts.runners.host import base_test
from vts.runners.host import const
from vts.runners.host import test_runner
import time
class VtsKernelCheckpointTest(base_test.BaseTestClass):
_CHECKPOINTTESTFILE = "/data/local/tmp/checkpointtest"
_ORIGINALVALUE = "original value"
_MODIFIEDVALUE = "modified value"
def getFstab(self):
self.dut.adb.root()
for prop in ["fstab_suffix", "hardware", "hardware.platform"]:
extension = self.dut.adb.shell("getprop ro.boot." + prop, no_except = True)
extension = extension[const.STDOUT]
if not extension:
continue
for filename in ["/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."]:
contents = self.dut.adb.shell("cat " + filename + extension, no_except = True)
if contents[const.EXIT_CODE] != 0:
continue
return contents[const.STDOUT]
return ""
def isCheckpoint(self):
fstab = self.getFstab().splitlines()
for line in fstab:
parts = line.split()
if len(parts) != 5: # fstab has five parts for each entry:
# [device-name] [mount-point] [type] [mount_flags] [fsmgr_flags]
continue
flags = parts[4] # the fsmgr_flags field is the fifth one, thus index 4
flags = flags.split(',')
if any(flag.startswith("checkpoint=") for flag in flags):
return True
return False
def setUpClass(self):
self.dut = self.android_devices[0]
self.shell = self.dut.shell
self.isCheckpoint_ = self.isCheckpoint()
def reboot(self):
self.dut.adb.reboot()
try:
self.dut.adb.wait_for_device(timeout=900)
except self.dut.adb.AdbError as e:
asserts.fail("Exception thrown waiting for device:" + e.msg())
# Should not be necessary, but without these retries, test fails
# regularly on taimen with Android Q
for i in range(1, 30):
try:
self.dut.adb.root()
break
except:
time.sleep(1)
for i in range(1, 30):
try:
self.dut.adb.shell("ls");
break
except:
time.sleep(1)
def checkBooted(self):
for i in range(1, 900):
result = self.dut.adb.shell("getprop sys.boot_completed")
try:
boot_completed = int(result)
asserts.assertEqual(boot_completed, 1)
return
except:
time.sleep(1)
asserts.fail("sys.boot_completed not set")
def testCheckpointEnabled(self):
result = self.dut.adb.shell("getprop ro.product.first_api_level")
try:
first_api_level = int(result)
asserts.assertTrue(first_api_level < 29 or self.isCheckpoint_,
"User Data Checkpoint is disabled")
except:
pass
def testRollback(self):
if not self.isCheckpoint_:
return
self.dut.adb.root()
# Make sure that we are fully booted so we don't get entangled in
# someone else's checkpoint
self.checkBooted()
# Create a file and initiate checkpoint
self.dut.adb.shell("setprop persist.vold.dont_commit_checkpoint 1")
self.dut.adb.shell("echo " + self._ORIGINALVALUE + " > " + self._CHECKPOINTTESTFILE)
result = self.dut.adb.shell("vdc checkpoint startCheckpoint 1", no_except = True)
asserts.assertEqual(result[const.EXIT_CODE], 0)
self.reboot()
# Modify the file but do not commit
self.dut.adb.shell("echo " + self._MODIFIEDVALUE + " > " + self._CHECKPOINTTESTFILE)
self.reboot()
# Check the file is unchanged
result = self.dut.adb.shell("cat " + self._CHECKPOINTTESTFILE)
asserts.assertEqual(result.strip(), self._ORIGINALVALUE)
# Clean up
self.dut.adb.shell("setprop persist.vold.dont_commit_checkpoint 0")
result = self.dut.adb.shell("vdc checkpoint commitChanges", no_except = True)
asserts.assertEqual(result[const.EXIT_CODE], 0)
self.reboot()
self.dut.adb.shell("rm " + self._CHECKPOINTTESTFILE)
def testCommit(self):
if not self.isCheckpoint_:
return
self.dut.adb.root()
# Make sure that we are fully booted so we don't get entangled in
# someone else's checkpoint
self.checkBooted()
# Create a file and initiate checkpoint
self.dut.adb.shell("setprop persist.vold.dont_commit_checkpoint 1")
self.dut.adb.shell("echo " + self._ORIGINALVALUE + " > " + self._CHECKPOINTTESTFILE)
result = self.dut.adb.shell("vdc checkpoint startCheckpoint 1", no_except = True)
asserts.assertEqual(result[const.EXIT_CODE], 0)
self.reboot()
# Modify the file and commit the checkpoint
self.dut.adb.shell("echo " + self._MODIFIEDVALUE + " > " + self._CHECKPOINTTESTFILE)
self.dut.adb.shell("setprop persist.vold.dont_commit_checkpoint 0")
result = self.dut.adb.shell("vdc checkpoint commitChanges", no_except = True)
asserts.assertEqual(result[const.EXIT_CODE], 0)
self.reboot()
# Check file has changed
result = self.dut.adb.shell("cat " + self._CHECKPOINTTESTFILE)
asserts.assertEqual(result.strip(), self._MODIFIEDVALUE)
# Clean up
self.dut.adb.shell("rm " + self._CHECKPOINTTESTFILE)
if __name__ == "__main__":
test_runner.main()