Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / cros / tests / cros_vm_test.py
1 #!/usr/bin/python
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.
5
6 """Integration test to test the basic functionality of cros flash/deploy.
7
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.
11 """
12
13 import logging
14
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
20
21
22 def _FormatLogContent(name, content):
23   """Helper function for printing out complete log content."""
24   return '\n'.join((
25       '----------- Start of %s log -----------\n' % name,
26       content,
27       '-----------  End of %s log -----------\n' % name,
28   ))
29
30
31 class TestError(Exception):
32   """Raised on any error during testing."""
33
34
35 class CrosCommandTest(object):
36   """Wrapper cros command tests."""
37
38   def __init__(self, board, image_path):
39     """Initialize CrosTest.
40
41     Args:
42       board: Board of the image under test.
43       image_path: Path to the VM image to test.
44     """
45     self.board = board
46     self.image_path = image_path
47     self.working_image_path = None
48     self.vm = None
49
50   def Cleanup(self):
51     """Cleans up any state at the end of the test."""
52     try:
53       if self.vm:
54         self.vm.Stop()
55         self.vm = None
56
57     except Exception:
58       logging.warning('Received error during cleanup', exc_info=True)
59
60   def Setup(self):
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)
67
68     self.vm = vm.VMInstance(self.working_image_path, tempdir=self.tempdir)
69     logging.info('Starting the vm on port %d.', self.vm.port)
70     self.vm.Start()
71
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
79     # tests for that.
80     cmd = ['cros', 'flash', '--debug', '--no-wipe', '--no-reboot',
81            device_addr, 'latest']
82     result = cros_build_lib.RunCommand(cmd, capture_output=True,
83                                        error_code_ok=True)
84
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')
89
90     logging.info('cros flash test completed successfully')
91
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]
100
101     # Unmerge the packages.
102     cmd = cmd_base + ['--unmerge'] + packages
103     result = cros_build_lib.RunCommand(cmd, capture_output=True,
104                                        enter_chroot=True,
105                                        error_code_ok=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.')
110
111     # Re-install the packages.
112     cmd = cmd_base + packages
113     result = cros_build_lib.RunCommand(cmd, capture_output=True,
114                                        enter_chroot=True,
115                                        error_code_ok=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.')
120
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:
125       try:
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))
134
135     logging.info('cros deploy test completed successfully')
136
137   @osutils.TempDirDecorator
138   def Run(self):
139     """Runs the tests."""
140     try:
141       self.Setup()
142       self.TestCrosFlash()
143       self.TestCrosDeploy()
144     finally:
145       self.Cleanup()
146
147     logging.info('All tests in cros_vm_test passed.')
148
149
150 def _ParseArguments(argv):
151   """Parses command line arguments."""
152   parser = commandline.ArgumentParser(caching=True)
153   parser.add_argument(
154       'board', help='Board of the image.')
155   parser.add_argument(
156       'image_path', help='Path to the image to test.')
157
158   return parser.parse_args(argv)
159
160
161 def main(argv):
162   """Main function of the script."""
163   options = _ParseArguments(argv)
164   options.Freeze()
165
166   logging.info('Starting cros_vm_test...')
167   test = CrosCommandTest(options.board, options.image_path)
168   test.Run()