2 # Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Integration test to test the basic functionality of cros flash/deploy.
8 This module contains a test that runs some sanity integration tests against
9 a VM. It starts a VM and runs `cros flash` to update the VM, and then
10 `cros deploy` to install packages to the VM.
15 from chromite.lib import commandline
16 from chromite.lib import cros_build_lib
17 from chromite.lib import osutils
18 from chromite.lib import remote_access
19 from chromite.lib import vm
22 def _FormatLogContent(name, content):
23 """Helper function for printing out complete log content."""
25 '----------- Start of %s log -----------\n' % name,
27 '----------- End of %s log -----------\n' % name,
31 class TestError(Exception):
32 """Raised on any error during testing."""
35 class CrosCommandTest(object):
36 """Wrapper cros command tests."""
38 def __init__(self, board, image_path):
39 """Initialize CrosTest.
42 board: Board of the image under test.
43 image_path: Path to the VM image to test.
46 self.image_path = image_path
47 self.working_image_path = None
51 """Cleans up any state at the end of the test."""
58 logging.warning('Received error during cleanup', exc_info=True)
61 """Creates and/or starts the VM instance."""
62 logging.info('Setting up image %s for vm testing.', self.image_path)
63 self.working_image_path = vm.CreateVMImage(
64 image=self.image_path, board=self.board, updatable=True,
65 dest_dir=self.tempdir)
66 logging.info('Using VM image at %s.', self.working_image_path)
68 self.vm = vm.VMInstance(self.working_image_path, tempdir=self.tempdir)
69 logging.info('Starting the vm on port %d.', self.vm.port)
72 def TestCrosFlash(self):
73 """Tests that we can flash the device with the latest image."""
74 logging.info('Testing flashing VM with cros flash...')
75 device_addr = 'ssh://%s:%d' % (remote_access.LOCALHOST, self.vm.port)
76 # We explicitly disable reboot after the update because VMs
77 # sometimes do not come back after reboot. `cros flash` does not
78 # need to verify the integrity of the updated image. We have AU
80 cmd = ['cros', 'flash', '--debug', '--no-wipe', '--no-reboot',
81 device_addr, 'latest']
82 result = cros_build_lib.RunCommand(cmd, capture_output=True,
85 if result.returncode != 0:
86 logging.error('Failed updating VM with image. Printing logs...\n%s',
87 _FormatLogContent('Cros Flash', result.error))
88 raise TestError('cros flash test failed')
90 logging.info('cros flash test completed successfully')
92 def TestCrosDeploy(self):
93 """Tests that we can deploy packages to the device."""
94 logging.info('Testing installing/uninstalling pacakges with cros deploy...')
95 device_addr = 'ssh://%s:%d' % (remote_access.LOCALHOST, self.vm.port)
96 packages = ['dev-python/cherrypy', 'app-portage/portage-utils']
97 # Set the installation root to /usr/local so that `cros deploy`
98 # does not attempt to remount rootfs (which leads to VM reboot).
99 cmd_base = ['cros', 'deploy', '--debug', '--root=/usr/local', device_addr]
101 # Unmerge the packages.
102 cmd = cmd_base + ['--unmerge'] + packages
103 result = cros_build_lib.RunCommand(cmd, capture_output=True,
106 if result.returncode != 0:
107 logging.error('Failed unmerging packages from VM. Printing logs...\n%s',
108 _FormatLogContent('Cros Deploy', result.error))
109 raise TestError('cros deploy unmerge test failed.')
111 # Re-install the packages.
112 cmd = cmd_base + packages
113 result = cros_build_lib.RunCommand(cmd, capture_output=True,
116 if result.returncode != 0:
117 logging.error('Failed deploying packages to VM. Printing logs...\n%s',
118 _FormatLogContent('Cros Deploy', result.error))
119 raise TestError('cros deploy test failed.')
121 # Verify that the packages are installed.
122 with remote_access.ChromiumOSDeviceHandler(
123 remote_access.LOCALHOST, port=self.vm.port,
124 base_dir=self.tempdir) as device:
126 device.RunCommand(['python', '-c', '"import cherrypy"'])
127 device.RunCommand(['qmerge', '-h'])
128 except remote_access.SSHConnectionError as e:
129 logging.error('Unable to connect to VM after deploy packages')
130 raise TestError('Unable to connect to VM: %s' % str(e))
131 except cros_build_lib.RunCommandError as e:
132 logging.error('Could not verify packages are installed')
133 raise TestError('Error verifying packages are installed: %s' % str(e))
135 logging.info('cros deploy test completed successfully')
137 @osutils.TempDirDecorator
139 """Runs the tests."""
143 self.TestCrosDeploy()
147 logging.info('All tests in cros_vm_test passed.')
150 def _ParseArguments(argv):
151 """Parses command line arguments."""
152 parser = commandline.ArgumentParser(caching=True)
154 'board', help='Board of the image.')
156 'image_path', help='Path to the image to test.')
158 return parser.parse_args(argv)
162 """Main function of the script."""
163 options = _ParseArguments(argv)
166 logging.info('Starting cros_vm_test...')
167 test = CrosCommandTest(options.board, options.image_path)