blob: 01b946949e934bb4457ea08955d9aa911e9551cc [file] [log] [blame]
Ryan Cuiafd6c5c2012-07-30 17:48:22 -07001#!/usr/bin/python
2# Copyright (c) 2012 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
Ryan Cuiafd6c5c2012-07-30 17:48:22 -07007import os
8import sys
9
10sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)),
11 '..', '..'))
Ryan Cuief91e702013-02-04 12:06:36 -080012
Ryan Cui686ec052013-02-12 16:39:41 -080013from chromite.cros.commands import cros_chrome_sdk_unittest
Ryan Cuief91e702013-02-04 12:06:36 -080014from chromite.lib import chrome_util
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070015from chromite.lib import cros_build_lib
16from chromite.lib import cros_test_lib
Ryan Cui686ec052013-02-12 16:39:41 -080017from chromite.lib import osutils
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070018from chromite.lib import partial_mock
19from chromite.lib import remote_access_unittest
20from chromite.scripts import deploy_chrome
21
Ryan Cuief91e702013-02-04 12:06:36 -080022
Brian Harringe7524372012-12-23 02:02:56 -080023# TODO(build): Finish test wrapper (http://crosbug.com/37517).
24# Until then, this has to be after the chromite imports.
25import mock
26
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070027
28# pylint: disable=W0212
29
30_REGULAR_TO = ('--to', 'monkey')
31_GS_PATH = 'gs://foon'
32
33
34def _ParseCommandLine(argv):
35 return deploy_chrome._ParseCommandLine(['--log-level', 'debug'] + argv)
36
37
38class InterfaceTest(cros_test_lib.OutputTestCase):
39 """Tests the commandline interface of the script."""
40
Ryan Cui686ec052013-02-12 16:39:41 -080041 BOARD = 'lumpy'
42
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070043 def testGsLocalPathUnSpecified(self):
44 """Test no chrome path specified."""
45 with self.OutputCapturer():
46 self.assertRaises2(SystemExit, _ParseCommandLine, list(_REGULAR_TO),
47 check_attrs={'code': 2})
48
49 def testGsPathSpecified(self):
50 """Test case of GS path specified."""
51 argv = list(_REGULAR_TO) + ['--gs-path', _GS_PATH]
52 _ParseCommandLine(argv)
53
54 def testLocalPathSpecified(self):
55 """Test case of local path specified."""
Ryan Cuia56a71e2012-10-18 18:40:35 -070056 argv = list(_REGULAR_TO) + ['--local-pkg-path', '/path/to/chrome']
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070057 _ParseCommandLine(argv)
58
59 def testNoTarget(self):
60 """Test no target specified."""
61 argv = ['--gs-path', _GS_PATH]
Ryan Cuief91e702013-02-04 12:06:36 -080062 self.assertParseError(argv)
63
64 def assertParseError(self, argv):
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070065 with self.OutputCapturer():
66 self.assertRaises2(SystemExit, _ParseCommandLine, argv,
67 check_attrs={'code': 2})
68
Ryan Cuief91e702013-02-04 12:06:36 -080069 def testStagingFlagsNoStrict(self):
70 """Errors out when --staging-flags is set without --strict."""
71 argv = ['--staging-only', '--build-dir=/path/to/nowhere',
Ryan Cui686ec052013-02-12 16:39:41 -080072 '--board=%s' % self.BOARD, '--staging-flags=highdpi']
Ryan Cuief91e702013-02-04 12:06:36 -080073 self.assertParseError(argv)
74
75 def testStrictNoBuildDir(self):
76 """Errors out when --strict is set without --build-dir."""
77 argv = ['--staging-only', '--strict', '--gs-path', _GS_PATH]
78 self.assertParseError(argv)
79
Ryan Cui686ec052013-02-12 16:39:41 -080080 def testNoBoardBuildDir(self):
81 argv = ['--staging-only', '--build-dir=/path/to/nowhere']
82 self.assertParseError(argv)
83
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070084
85class DeployChromeMock(partial_mock.PartialMock):
86
87 TARGET = 'chromite.scripts.deploy_chrome.DeployChrome'
88 ATTRS = ('_CheckRootfsWriteable', '_DisableRootfsVerification',
89 '_KillProcsIfNeeded')
90
Ryan Cuie18f24f2012-12-03 18:39:55 -080091 def __init__(self, disable_ok=True):
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070092 partial_mock.PartialMock.__init__(self)
93 self.disable_ok = disable_ok
94 self.rootfs_writeable = False
95 # Target starts off as having rootfs verification enabled.
Ryan Cuie18f24f2012-12-03 18:39:55 -080096 self.rsh_mock = remote_access_unittest.RemoteShMock()
Ryan Cuiafd6c5c2012-07-30 17:48:22 -070097 self.MockMountCmd(1)
98
99 def MockMountCmd(self, returnvalue):
100 def hook(_inst, *_args, **_kwargs):
101 self.rootfs_writeable = True
102
103 self.rsh_mock.AddCmdResult(deploy_chrome.MOUNT_RW_COMMAND,
104 returnvalue,
105 side_effect=None if returnvalue else hook)
106
Ryan Cui4d6fca92012-12-13 16:41:56 -0800107 def PreStart(self):
108 self.rsh_mock.start()
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700109
Ryan Cui4d6fca92012-12-13 16:41:56 -0800110 def PreStop(self):
111 self.rsh_mock.stop()
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700112
113 def _CheckRootfsWriteable(self, _inst):
114 return self.rootfs_writeable
115
116 def _DisableRootfsVerification(self, _inst):
117 self.MockMountCmd(int(not self.disable_ok))
118
119 def _KillProcsIfNeeded(self, _inst):
120 # Fully stub out for now.
121 pass
122
123
Ryan Cuief91e702013-02-04 12:06:36 -0800124class DeployTest(cros_test_lib.MockTempDirTestCase):
125 def _GetDeployChrome(self, args):
126 options, _ = _ParseCommandLine(args)
Ryan Cuia56a71e2012-10-18 18:40:35 -0700127 return deploy_chrome.DeployChrome(
128 options, self.tempdir, os.path.join(self.tempdir, 'staging'))
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700129
130 def setUp(self):
Ryan Cuif1416f32013-01-22 18:43:41 -0800131 self.deploy_mock = self.StartPatcher(DeployChromeMock())
Ryan Cuief91e702013-02-04 12:06:36 -0800132 self.deploy = self._GetDeployChrome(
133 list(_REGULAR_TO) + ['--gs-path', _GS_PATH])
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700134
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700135
Ryan Cuief91e702013-02-04 12:06:36 -0800136class TestPrepareTarget(DeployTest):
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700137 """Testing disabling of rootfs verification and RO mode."""
138
139 def testSuccess(self):
140 """Test the working case."""
141 self.deploy._PrepareTarget()
142
143 def testDisableRootfsVerificationFailure(self):
144 """Test failure to disable rootfs verification."""
145 self.deploy_mock.disable_ok = False
146 self.assertRaises(cros_build_lib.RunCommandError,
147 self.deploy._PrepareTarget)
148
149 def testMountRwFailure(self):
150 """The mount command returncode was 0 but rootfs is still readonly."""
151 with mock.patch.object(deploy_chrome.DeployChrome, '_CheckRootfsWriteable',
152 auto_spec=True) as m:
153 m.return_value = False
154 self.assertRaises(SystemExit, self.deploy._PrepareTarget)
155
156 def testMountRwSuccessFirstTime(self):
157 """We were able to mount as RW the first time."""
158 self.deploy_mock.MockMountCmd(0)
159 self.deploy._PrepareTarget()
160
161
162PROC_MOUNTS = """\
163rootfs / rootfs rw 0 0
164/dev/root / ext2 %s,relatime,user_xattr,acl 0 0
165devtmpfs /dev devtmpfs rw,relatime,size=970032k,nr_inodes=242508,mode=755 0 0
166none /proc proc rw,nosuid,nodev,noexec,relatime 0 0
167"""
168
169
Ryan Cuief91e702013-02-04 12:06:36 -0800170class TestCheckRootfs(DeployTest):
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700171 """Test Rootfs RW check functionality."""
172
173 def setUp(self):
174 self.deploy_mock.UnMockAttr('_CheckRootfsWriteable')
175
176 def MockProcMountsCmd(self, output):
177 self.deploy_mock.rsh_mock.AddCmdResult('cat /proc/mounts', output=output)
178
179 def testCheckRootfsWriteableFalse(self):
180 """Correct results with RO."""
181 self.MockProcMountsCmd(PROC_MOUNTS % 'ro')
182 self.assertFalse(self.deploy._CheckRootfsWriteable())
183
184 def testCheckRootfsWriteableTrue(self):
185 """Correct results with RW."""
186 self.MockProcMountsCmd(PROC_MOUNTS % 'rw')
187 self.assertTrue(self.deploy._CheckRootfsWriteable())
188
189
Ryan Cuief91e702013-02-04 12:06:36 -0800190class TestUiJobStarted(DeployTest):
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700191 """Test detection of a running 'ui' job."""
192
Ryan Cuif2d1a582013-02-19 14:08:13 -0800193 def MockStatusUiCmd(self, **kwargs):
194 self.deploy_mock.rsh_mock.AddCmdResult('status ui', **kwargs)
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700195
196 def testUiJobStartedFalse(self):
197 """Correct results with a stopped job."""
Ryan Cuif2d1a582013-02-19 14:08:13 -0800198 self.MockStatusUiCmd(output='ui stop/waiting')
199 self.assertFalse(self.deploy._CheckUiJobStarted())
200
201 def testNoUiJob(self):
202 """Correct results when the job doesn't exist."""
203 self.MockStatusUiCmd(error='start: Unknown job: ui', returncode=1)
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700204 self.assertFalse(self.deploy._CheckUiJobStarted())
205
206 def testCheckRootfsWriteableTrue(self):
207 """Correct results with a running job."""
Ryan Cuif2d1a582013-02-19 14:08:13 -0800208 self.MockStatusUiCmd(output='ui start/running, process 297')
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700209 self.assertTrue(self.deploy._CheckUiJobStarted())
210
211
Ryan Cuief91e702013-02-04 12:06:36 -0800212class StagingTest(cros_test_lib.MockTempDirTestCase):
213 """Test user-mode and ebuild-mode staging functionality."""
214
215 def setUp(self):
Ryan Cuief91e702013-02-04 12:06:36 -0800216 self.staging_dir = os.path.join(self.tempdir, 'staging')
217 self.build_dir = os.path.join(self.tempdir, 'build_dir')
Ryan Cui686ec052013-02-12 16:39:41 -0800218 self.common_flags = ['--build-dir', self.build_dir,
219 '--board=lumpy', '--staging-only', '--cache-dir',
220 self.tempdir]
Ryan Cuia0215a72013-02-14 16:20:45 -0800221 self.sdk_mock = self.StartPatcher(cros_chrome_sdk_unittest.SDKFetcherMock())
Ryan Cui686ec052013-02-12 16:39:41 -0800222 self.PatchObject(
223 osutils, 'SourceEnvironment', autospec=True,
224 return_value={'STRIP': 'x86_64-cros-linux-gnu-strip'})
Ryan Cuief91e702013-02-04 12:06:36 -0800225
226 def testEmptyDeploySuccess(self):
227 """User-mode staging - stage whatever we can find."""
228 options, _ = _ParseCommandLine(self.common_flags)
229 deploy_chrome._PrepareStagingDir(
230 options, self.tempdir, self.staging_dir)
231
232 def testEmptyDeployStrict(self):
233 """ebuild-mode staging - stage only things we want."""
234 options, _ = _ParseCommandLine(
235 self.common_flags + ['--gyp-defines', 'chromeos=1', '--strict'])
Ryan Cui686ec052013-02-12 16:39:41 -0800236 chrome_util.MissingPathError(deploy_chrome._PrepareStagingDir,
237 options, self.tempdir, self.staging_dir)
238
Ryan Cuief91e702013-02-04 12:06:36 -0800239 self.assertRaises(
240 chrome_util.MissingPathError, deploy_chrome._PrepareStagingDir,
241 options, self.tempdir, self.staging_dir)
242
243
Ryan Cuiafd6c5c2012-07-30 17:48:22 -0700244if __name__ == '__main__':
245 cros_test_lib.main()