Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / scripts / pushimage_unittest.py
1 #!/usr/bin/python
2 # Copyright (c) 2013 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 """Unittests for pushimage.py"""
7
8 from __future__ import print_function
9
10 import logging
11 import os
12 import sys
13
14 sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)),
15                                 '..', '..'))
16 from chromite.lib import cros_build_lib
17 from chromite.lib import cros_test_lib
18 from chromite.lib import git
19 from chromite.lib import gs_unittest
20 from chromite.lib import osutils
21 from chromite.lib import partial_mock
22 from chromite.lib import signing
23 from chromite.scripts import pushimage
24
25
26 class InputInsnsTest(cros_test_lib.MockTestCase):
27   """Tests for InputInsns"""
28
29   def testBasic(self):
30     """Simple smoke test"""
31     insns = pushimage.InputInsns('test.board')
32     insns.GetInsnFile('recovery')
33     self.assertEqual(insns.GetChannels(), ['dev', 'canary'])
34     self.assertEqual(insns.GetKeysets(), ['stumpy-mp-v3'])
35
36   def testGetInsnFile(self):
37     """Verify various inputs result in right insns path"""
38     testdata = (
39         ('UPPER_CAPS', 'UPPER_CAPS'),
40         ('recovery', 'test.board'),
41         ('firmware', 'test.board.firmware'),
42         ('factory', 'test.board.factory'),
43     )
44     insns = pushimage.InputInsns('test.board')
45     for image_type, filename in testdata:
46       ret = insns.GetInsnFile(image_type)
47       self.assertEqual(os.path.basename(ret), '%s.instructions' % (filename))
48
49   def testSplitCfgField(self):
50     """Verify splitting behavior behaves"""
51     testdata = (
52         ('', []),
53         ('a b c', ['a', 'b', 'c']),
54         ('a, b', ['a', 'b']),
55         ('a,b', ['a', 'b']),
56         ('a,\tb', ['a', 'b']),
57         ('a\tb', ['a', 'b']),
58     )
59     for val, exp in testdata:
60       ret = pushimage.InputInsns.SplitCfgField(val)
61       self.assertEqual(ret, exp)
62
63   def testOutputInsnsBasic(self):
64     """Verify output instructions are sane"""
65     exp_content = """[insns]
66 keyset = stumpy-mp-v3
67 channel = dev canary
68 chromeos_shell = false
69 ensure_no_password = true
70 firmware_update = true
71 security_checks = true
72 create_nplusone = true
73
74 [general]
75 """
76
77     insns = pushimage.InputInsns('test.board')
78     m = self.PatchObject(osutils, 'WriteFile')
79     insns.OutputInsns('recovery', '/bogus', {}, {})
80     self.assertTrue(m.called)
81     content = m.call_args_list[0][0][1]
82     self.assertEqual(content.rstrip(), exp_content.rstrip())
83
84   def testOutputInsnsReplacements(self):
85     """Verify output instructions can be updated"""
86     exp_content = """[insns]
87 keyset = batman
88 channel = dev
89 chromeos_shell = false
90 ensure_no_password = true
91 firmware_update = true
92 security_checks = true
93 create_nplusone = true
94
95 [general]
96 board = board
97 config_board = test.board
98 """
99     sect_insns = {
100         'channel': 'dev',
101         'keyset': 'batman',
102     }
103     sect_general = {
104         'config_board': 'test.board',
105         'board': 'board',
106     }
107
108     insns = pushimage.InputInsns('test.board')
109     m = self.PatchObject(osutils, 'WriteFile')
110     insns.OutputInsns('recovery', '/a/file', sect_insns, sect_general)
111     self.assertTrue(m.called)
112     content = m.call_args_list[0][0][1]
113     self.assertEqual(content.rstrip(), exp_content.rstrip())
114
115
116 class MarkImageToBeSignedTest(gs_unittest.AbstractGSContextTest):
117   """Tests for MarkImageToBeSigned()"""
118
119   def setUp(self):
120     # Minor optimization -- we call this for logging purposes in the main
121     # code, but don't really care about it for testing.  It just slows us.
122     self.PatchObject(git, 'RunGit',
123                      return_value=cros_build_lib.CommandResult(output='1234\n'))
124
125   def testBasic(self):
126     """Simple smoke test"""
127     tbs_base = 'gs://some-bucket'
128     insns_path = 'chan/board/ver/file.instructions'
129     tbs_file = '%s/tobesigned/90,chan,board,ver,file.instructions' % tbs_base
130     ret = pushimage.MarkImageToBeSigned(self.ctx, tbs_base, insns_path, 90)
131     self.assertEqual(ret, tbs_file)
132
133   def testPriority(self):
134     """Verify diff priority values get used correctly"""
135     for prio, sprio in ((0, '00'), (9, '09'), (35, '35'), (99, '99')):
136       ret = pushimage.MarkImageToBeSigned(self.ctx, '', '', prio)
137       self.assertEquals(ret, '/tobesigned/%s,' % sprio)
138
139   def testBadPriority(self):
140     """Verify we reject bad priority values"""
141     for prio in (-10, -1, 100, 91239):
142       self.assertRaises(ValueError, pushimage.MarkImageToBeSigned, self.ctx,
143                         '', '', prio)
144
145   def testTbsFile(self):
146     """Make sure the tbs file we write has useful data"""
147     WriteFile = osutils.WriteFile
148     def _write_check(*args, **kwargs):
149       # We can't mock every call, so do the actual write for most.
150       WriteFile(*args, **kwargs)
151
152     m = self.PatchObject(osutils, 'WriteFile')
153     m.side_effect = _write_check
154     pushimage.MarkImageToBeSigned(self.ctx, '', '', 50)
155     # We assume the first call is the one we care about.
156     self.assertTrue(m.called)
157     content = m.call_args_list[0][0][1]
158     self.assertIn('USER=', content)
159     self.assertIn('HOSTNAME=', content)
160     self.assertIn('GIT_REV=1234', content)
161     self.assertIn('\n', content)
162
163   def testTbsUpload(self):
164     """Make sure we actually try to upload the file"""
165     pushimage.MarkImageToBeSigned(self.ctx, '', '', 50)
166     self.gs_mock.assertCommandContains(['cp', '--'])
167
168
169 class PushImageTests(gs_unittest.AbstractGSContextTest):
170   """Tests for PushImage()"""
171
172   def setUp(self):
173     self.mark_mock = self.PatchObject(pushimage, 'MarkImageToBeSigned')
174
175   def testBasic(self):
176     """Simple smoke test"""
177     EXPECTED = {
178         'canary': [
179             'gs://chromeos-releases/canary-channel/test.board-hi/5126.0.0/'
180               'ChromeOS-recovery-R34-5126.0.0-test.board-hi.instructions'],
181         'dev': [
182             'gs://chromeos-releases/dev-channel/test.board-hi/5126.0.0/'
183               'ChromeOS-recovery-R34-5126.0.0-test.board-hi.instructions'],
184     }
185     urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
186                                profile='hi')
187
188     self.assertEqual(urls, EXPECTED)
189
190   def testBasicMock(self):
191     """Simple smoke test in mock mode"""
192     pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
193                         dry_run=True, mock=True)
194
195   def testBadVersion(self):
196     """Make sure we barf on bad version strings"""
197     self.assertRaises(ValueError, pushimage.PushImage, '', '', 'asdf')
198
199   def testNoInsns(self):
200     """Boards w/out insn files should get skipped"""
201     urls = pushimage.PushImage('/src', 'a bad bad board', 'R34-5126.0.0')
202     self.assertEqual(self.gs_mock.call_count, 0)
203     self.assertEqual(urls, None)
204
205   def testSignTypesRecovery(self):
206     """Only sign the requested recovery type"""
207     EXPECTED = {
208         'canary': [
209             'gs://chromeos-releases/canary-channel/test.board/5126.0.0/'
210               'ChromeOS-recovery-R34-5126.0.0-test.board.instructions'],
211         'dev': [
212             'gs://chromeos-releases/dev-channel/test.board/5126.0.0/'
213               'ChromeOS-recovery-R34-5126.0.0-test.board.instructions'],
214     }
215
216     urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
217                                sign_types=['recovery'])
218     self.assertEqual(self.gs_mock.call_count, 18)
219     self.assertTrue(self.mark_mock.called)
220     self.assertEqual(urls, EXPECTED)
221
222   def testSignTypesNone(self):
223     """Verify nothing is signed when we request an unavailable type"""
224     urls = pushimage.PushImage('/src', 'test.board', 'R34-5126.0.0',
225                                sign_types=['nononononono'])
226     self.assertEqual(self.gs_mock.call_count, 16)
227     self.assertFalse(self.mark_mock.called)
228     self.assertEqual(urls, {})
229
230   def testGsError(self):
231     """Verify random GS errors don't make us blow up entirely"""
232     self.gs_mock.AddCmdResult(partial_mock.In('stat'), returncode=1,
233                               output='gobblety gook\n')
234     with cros_test_lib.LoggingCapturer('chromite'):
235       self.assertRaises(pushimage.PushError, pushimage.PushImage, '/src',
236                         'test.board', 'R34-5126.0.0')
237
238
239 class MainTests(cros_test_lib.MockTestCase):
240   """Tests for main()"""
241
242   def setUp(self):
243     self.PatchObject(pushimage, 'PushImage')
244
245   def testBasic(self):
246     """Simple smoke test"""
247     pushimage.main(['--board', 'test.board', '/src', '--yes'])
248
249
250 if __name__ == '__main__':
251   # Use our local copy of insns for testing as the main one is not
252   # available in the public manifest.
253   signing.INPUT_INSN_DIR = signing.TEST_INPUT_INSN_DIR
254
255   # Run the tests.
256   cros_test_lib.main(level=logging.INFO)