1#!/usr/bin/python
2
3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Short integration tests for full_release_test."""
8
9import mox
10import os
11import tempfile
12import shutil
13import unittest
14
15import common
16from autotest_lib.site_utils.autoupdate import full_release_test
17# This is convoluted because of the way we pull in gsutil_util.
18# pylint: disable-msg=W0611
19from autotest_lib.site_utils.autoupdate import test_image
20from test_image import gsutil_util
21
22
23def _ControlFileContainsLine(control_file, line):
24    """Returns true if the string |control_file| contains line |line|."""
25    for current_line in control_file.splitlines():
26        if current_line == line:
27            return True
28    else:
29        return False
30
31
32def _DoesControlFileHaveSourceTarget(control_file_path, src, target):
33    """Returns true if control file has src and target correctly filled in."""
34    with open(control_file_path, 'r') as f:
35        control_file = f.read()
36        if not _ControlFileContainsLine(
37                control_file, "source_release = '%s'" % src):
38            print 'source_release does not match'
39            return False
40
41        if not _ControlFileContainsLine(
42                control_file, "target_release = '%s'" % target):
43          print 'target_release does not match'
44          return False
45
46    return True
47
48
49class ParseVersionsTests(unittest.TestCase):
50    """Tests various version parsing functions."""
51
52    def setUp(self):
53        self.config_gen = full_release_test.TestConfigGenerator
54
55    def testParseBuildVersion(self):
56        """Tests for _parse_build_version."""
57        build_version = 'R27-3905.0.0'
58        self.assertEquals(('R27', '3905.0.0'),
59                          self.config_gen._parse_build_version(build_version))
60        build_version = 'R41-6588.0.2014_12_16_1130-a1'
61        self.assertEquals(('R41', '6588.0.2014_12_16_1130-a1'),
62                          self.config_gen._parse_build_version(build_version))
63
64    def testParseDeltaFilename(self):
65        """"Tests for _parse_delta_filename."""
66        delta_filename = 'chromeos_R27-390.0.0_R29-395.0.0_stumpy_delta_dev.bin'
67        self.assertEquals(('R27-390.0.0', 'R29-395.0.0'),
68                          self.config_gen._parse_delta_filename(delta_filename))
69
70        # On non-release builds, delta filenames have a date portion as well.
71        delta_filename = 'chromeos_R41-6588.0.2014_12_16_1130-a1_R41-6588.0.2014_12_16_1130-a1_stumpy_delta_dev.bin'
72        self.assertEquals(('R41-6588.0.2014_12_16_1130-a1', 'R41-6588.0.2014_12_16_1130-a1'),
73                          self.config_gen._parse_delta_filename(delta_filename))
74
75class FullReleaseTestTests(mox.MoxTestBase):
76    """Tests for the full_release_test.py test harness."""
77
78
79    def setUp(self):
80        """Common setUp creates tmpdir."""
81        mox.MoxTestBase.setUp(self)
82        self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
83        self.tmpdir = tempfile.mkdtemp('control')
84
85
86    def tearDown(self):
87        """Common tearDown removes tmpdir."""
88        mox.MoxTestBase.tearDown(self)
89        shutil.rmtree(self.tmpdir)
90
91
92    def testIntegrationNmoBoard(self):
93        """Tests that we successfully generate a nmo control file."""
94        board = 'x86-mario'
95        branch = '24'
96        target = '3000.0.0'
97        src = '2999.0.0'
98
99        argv = ['--nmo',
100                '--dump_dir', self.tmpdir,
101                '--dump',
102                target, board]
103
104        # Return npo delta
105        gsutil_util.GSUtilRun(mox.And(
106                mox.StrContains('gsutil cat'),
107                mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
108                AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % (
109                        branch, src, branch, target, board))
110        # Return target full payload
111        gsutil_util.GSUtilRun(mox.And(
112                mox.StrContains('gsutil cat'),
113                mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
114                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
115                        branch, src, board))
116
117        self.mox.ReplayAll()
118        self.assertEquals(full_release_test.main(argv), 0)
119        self.assertTrue(_DoesControlFileHaveSourceTarget(
120                os.path.join(self.tmpdir, board, 'control.nmo_delta_%s' % src),
121                src, target))
122        self.mox.VerifyAll()
123
124
125    def testIntegrationNpoBoard(self):
126        """Tests that we successfully generate a npo control file."""
127        board = 'x86-mario'
128        branch = '24'
129        target = '3000.0.0'
130        src = '3000.0.0'
131
132        argv = ['--npo',
133                '--dump_dir', self.tmpdir,
134                '--dump',
135                target, board]
136
137        # Return npo delta
138        gsutil_util.GSUtilRun(mox.And(
139                mox.StrContains('gsutil cat'),
140                mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
141                AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % (
142                        branch, src, branch, target, board))
143        # Return target full payload
144        gsutil_util.GSUtilRun(mox.And(
145                mox.StrContains('gsutil cat'),
146                mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
147                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
148                        branch, src, board))
149        self.mox.ReplayAll()
150        self.assertEquals(full_release_test.main(argv), 0)
151        self.assertTrue(_DoesControlFileHaveSourceTarget(
152                os.path.join(self.tmpdir, board, 'control.npo_delta_%s' % src),
153                src, target))
154        self.mox.VerifyAll()
155
156
157    def testIntegrationNpoWithArchiveUrl(self):
158        """Successfully generate a npo control file with custom url."""
159        board = 'x86-mario'
160        branch = '24'
161        target = '3000.0.0'
162        src = '3000.0.0'
163        archive_url = 'gs://chromeos-image-archive/blah-dir/not_a_version'
164
165        argv = ['--npo',
166                '--dump_dir', self.tmpdir,
167                '--dump',
168                '--archive_url', archive_url,
169                target, board]
170
171        # Return npo delta
172        gsutil_util.GSUtilRun(mox.And(
173                mox.StrContains('gsutil cat'),
174                mox.StrContains(archive_url)), mox.IgnoreArg()).\
175                AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % (
176                        branch, src, branch, target, board))
177        # Return target full payload
178        gsutil_util.GSUtilRun(mox.And(
179                mox.StrContains('gsutil cat'),
180                mox.StrContains(archive_url)), mox.IgnoreArg()).\
181                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
182                        branch, src, board))
183        self.mox.ReplayAll()
184        self.assertEquals(full_release_test.main(argv), 0)
185        self.assertTrue(_DoesControlFileHaveSourceTarget(
186                os.path.join(self.tmpdir, board, 'control.npo_delta_%s' % src),
187                src, target))
188        self.mox.VerifyAll()
189
190
191    def testIntegrationNpoAllBoards(self):
192        """Tests that we successfully generate a npo control file 4 all boards.
193        """
194        boards = ['stumpy', 'lumpy', 'bumpy']
195        branch = '24'
196        target = '3000.0.0'
197        src = '3000.0.0'
198
199        argv = ['--npo',
200                '-n',
201                target] + boards
202
203        for board in boards:
204            # Return npo delta
205            gsutil_util.GSUtilRun(mox.And(
206                    mox.StrContains('gsutil cat'),
207                    mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
208                    AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % (
209                            branch, src, branch, target, board))
210            # Return target full payload
211            gsutil_util.GSUtilRun(mox.And(
212                    mox.StrContains('gsutil cat'),
213                    mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
214                    AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
215                            branch, src, board))
216
217        self.mox.ReplayAll()
218        self.assertEquals(full_release_test.main(argv), 0)
219        self.mox.VerifyAll()
220
221        self.mox.ResetAll()
222        # Verify we still run all of them even if one fails.
223        bad_board = 'stumpy'
224        for board in boards:
225            # Return npo delta
226            if board == bad_board:
227                gsutil_util.GSUtilRun(mox.And(
228                        mox.StrContains('gsutil cat'),
229                        mox.StrContains('%s/UPLOADED' % target)),
230                                        mox.IgnoreArg()).\
231                        AndReturn('NO DELTAS FOR YOU')
232                continue
233
234            gsutil_util.GSUtilRun(mox.And(
235                    mox.StrContains('gsutil cat'),
236                    mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
237                    AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % (
238                            branch, src, branch, target, board))
239
240            # Return target full payload
241            gsutil_util.GSUtilRun(mox.And(
242                    mox.StrContains('gsutil cat'),
243                    mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
244                    AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
245                            branch, src, board))
246
247        self.mox.ReplayAll()
248        self.assertEquals(full_release_test.main(argv), 0)
249        self.mox.VerifyAll()
250
251
252    def testIntegrationSpecificBoard(self):
253        """Tests that we successfully generate a specific control file."""
254        board = 'x86-mario'
255        branch = '24'
256        target = '3000.0.0'
257        src = '1234.0.0'
258
259        argv = ['--specific', src,
260                '--dump_dir', self.tmpdir,
261                '--dump',
262                target, board]
263
264        # Return target full payload
265        gsutil_util.GSUtilRun(mox.And(
266                mox.StrContains('gsutil cat'),
267                mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
268                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
269                        branch, target, board))
270        # Return src full payload
271        gsutil_util.GSUtilRun(mox.And(
272                mox.StrContains('gsutil cat'),
273                mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
274                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
275                        branch, src, board))
276        self.mox.ReplayAll()
277        self.assertEquals(full_release_test.main(argv), 0)
278        self.assertTrue(_DoesControlFileHaveSourceTarget(
279                os.path.join(self.tmpdir, board,
280                             'control.specific_full_%s' % src),
281                src, target))
282        self.mox.VerifyAll()
283
284
285    def testIntegrationSpecificBoardFail(self):
286        """Tests we don't generate a specific test if either payload missing."""
287        board = 'x86-mario'
288        branch = '24'
289        target = '3000.0.0'
290        src = '1234.0.0'
291
292        argv = ['--specific', src,
293                '--dump_dir', self.tmpdir,
294                '--dump',
295                target, board]
296
297        # Return target full payload
298        gsutil_util.GSUtilRun(mox.And(
299                mox.StrContains('gsutil cat'),
300                mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
301                AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % (
302                        branch, target, board))
303        # No src full payload
304        gsutil_util.GSUtilRun(mox.And(
305                mox.StrContains('gsutil cat'),
306                mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\
307                AndReturn('SOME OTHER DATA')
308        self.mox.ReplayAll()
309        self.assertEquals(full_release_test.main(argv), 1)
310        self.mox.VerifyAll()
311
312        self.mox.ResetAll()
313        # Return target full payload
314        gsutil_util.GSUtilRun(mox.And(
315                mox.StrContains('gsutil cat'),
316                mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\
317                AndReturn('SOME OTHER DATA')
318        self.mox.ReplayAll()
319        self.assertEquals(full_release_test.main(argv), 1)
320        self.mox.VerifyAll()
321
322
323if __name__ == '__main__':
324    unittest.main()
325