Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / cbuildbot / commands_unittest.py
1 #!/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 """Unittests for commands."""
7
8 from __future__ import print_function
9
10 import base64
11 import os
12 import sys
13
14 from StringIO import StringIO
15
16 import constants
17 sys.path.insert(0, constants.SOURCE_ROOT)
18 from chromite.cbuildbot import commands
19 from chromite.cbuildbot import failures_lib
20 from chromite.lib import cros_build_lib_unittest
21 from chromite.lib import cros_build_lib
22 from chromite.lib import cros_test_lib
23 from chromite.lib import gs
24 from chromite.lib import git
25 from chromite.lib import gob_util
26 from chromite.lib import osutils
27 from chromite.lib import partial_mock
28 from chromite.scripts import pushimage
29
30 # TODO(build): Finish test wrapper (http://crosbug.com/37517).
31 # Until then, this has to be after the chromite imports.
32 import mock
33
34
35 # pylint: disable=W0212
36 class RunBuildScriptTest(cros_test_lib.TempDirTestCase):
37   """Test RunBuildScript in a variety of cases."""
38
39   def _assertRunBuildScript(self, in_chroot=False, error=None, raises=None,
40                             **kwargs):
41     """Test the RunBuildScript function.
42
43     Args:
44       in_chroot: Whether to enter the chroot or not.
45       error: error result message to simulate.
46       raises: If the command should fail, the exception to be raised.
47       kwargs: Extra kwargs passed to RunBuildScript.
48     """
49     # Write specified error message to status file.
50     def WriteError(_cmd, extra_env=None, **_kwargs):
51       if extra_env is not None and error is not None:
52         status_file = extra_env['PARALLEL_EMERGE_STATUS_FILE']
53         osutils.WriteFile(status_file, error)
54
55     buildroot = self.tempdir
56     osutils.SafeMakedirs(os.path.join(buildroot, '.repo'))
57     if error is not None:
58       osutils.SafeMakedirs(os.path.join(buildroot, 'chroot', 'tmp'))
59
60     # Run the command, throwing an exception if it fails.
61     with cros_build_lib_unittest.RunCommandMock() as m:
62       cmd = ['example', 'command']
63       sudo_cmd = ['sudo', '--'] + cmd
64       returncode = 1 if raises else 0
65       m.AddCmdResult(cmd, returncode=returncode, side_effect=WriteError)
66       m.AddCmdResult(sudo_cmd, returncode=returncode, side_effect=WriteError)
67       with mock.patch.object(git, 'ReinterpretPathForChroot',
68                              side_effect=lambda x: x):
69         with cros_test_lib.LoggingCapturer():
70           # If the script failed, the exception should be raised and printed.
71           if raises:
72             self.assertRaises(raises, commands.RunBuildScript, buildroot,
73                               cmd, enter_chroot=in_chroot, **kwargs)
74           else:
75             commands.RunBuildScript(buildroot, cmd, enter_chroot=in_chroot,
76                                     **kwargs)
77
78   def testSuccessOutsideChroot(self):
79     """Test executing a command outside the chroot."""
80     self._assertRunBuildScript()
81
82   def testSuccessInsideChrootWithoutTempdir(self):
83     """Test executing a command inside a chroot without a tmp dir."""
84     self._assertRunBuildScript(in_chroot=True)
85
86   def testSuccessInsideChrootWithTempdir(self):
87     """Test executing a command inside a chroot with a tmp dir."""
88     self._assertRunBuildScript(in_chroot=True, error='')
89
90   def testFailureOutsideChroot(self):
91     """Test a command failure outside the chroot."""
92     self._assertRunBuildScript(raises=failures_lib.BuildScriptFailure)
93
94   def testFailureInsideChrootWithoutTempdir(self):
95     """Test a command failure inside the chroot without a temp directory."""
96     self._assertRunBuildScript(in_chroot=True,
97                                raises=failures_lib.BuildScriptFailure)
98
99   def testFailureInsideChrootWithTempdir(self):
100     """Test a command failure inside the chroot with a temp directory."""
101     self._assertRunBuildScript(in_chroot=True, error='',
102                                raises=failures_lib.BuildScriptFailure)
103
104   def testPackageBuildFailure(self):
105     """Test detecting a package build failure."""
106     self._assertRunBuildScript(in_chroot=True, error=constants.CHROME_CP,
107                                raises=failures_lib.PackageBuildFailure)
108
109   def testSuccessWithSudo(self):
110     """Test a command run with sudo."""
111     self._assertRunBuildScript(in_chroot=False, sudo=True)
112     self._assertRunBuildScript(in_chroot=True, sudo=True)
113
114
115 class RunTestSuiteTest(cros_build_lib_unittest.RunCommandTempDirTestCase):
116   """Test RunTestSuite functionality."""
117
118   TEST_BOARD = 'x86-generic'
119   BUILD_ROOT = '/fake/root'
120
121   def _RunTestSuite(self, test_type):
122     commands.RunTestSuite(self.tempdir, self.TEST_BOARD, self.BUILD_ROOT,
123                           '/tmp/taco', archive_dir='/fake/root',
124                           whitelist_chrome_crashes=False,
125                           test_type=test_type)
126
127   def testFull(self):
128     """Test running FULL config."""
129     self._RunTestSuite(constants.FULL_AU_TEST_TYPE)
130     self.assertCommandContains(['--quick'], expected=False)
131     self.assertCommandContains(['--only_verify'], expected=False)
132
133   def testSimple(self):
134     """Test SIMPLE config."""
135     self._RunTestSuite(constants.SIMPLE_AU_TEST_TYPE)
136     self.assertCommandContains(['--quick'])
137
138   def testSmoke(self):
139     """Test SMOKE config."""
140     self._RunTestSuite(constants.SMOKE_SUITE_TEST_TYPE)
141     self.assertCommandContains(['--quick', '--only_verify'])
142
143
144 class ChromeSDKTest(cros_build_lib_unittest.RunCommandTempDirTestCase):
145   """Basic tests for ChromeSDK commands with RunCommand mocked out."""
146   BOARD = 'daisy_foo'
147   EXTRA_ARGS = ('--monkey', 'banana')
148   EXTRA_ARGS2 = ('--donkey', 'kong')
149   CHROME_SRC = 'chrome_src'
150   CMD = ['bar', 'baz']
151   CWD = 'fooey'
152
153   def setUp(self):
154     self.inst = commands.ChromeSDK(self.CWD, self.BOARD)
155
156   def testRunCommand(self):
157     """Test that running a command is possible."""
158     self.inst.Run(self.CMD)
159     self.assertCommandContains([self.BOARD] + self.CMD, cwd=self.CWD)
160
161   def testRunCommandKwargs(self):
162     """Exercise optional arguments."""
163     custom_inst = commands.ChromeSDK(
164         self.CWD, self.BOARD, extra_args=list(self.EXTRA_ARGS),
165         chrome_src=self.CHROME_SRC, debug_log=True)
166     custom_inst.Run(self.CMD, list(self.EXTRA_ARGS2))
167     self.assertCommandContains(['debug', self.BOARD] + list(self.EXTRA_ARGS) +
168                                list(self.EXTRA_ARGS2) + self.CMD, cwd=self.CWD)
169
170   def testNinja(self):
171     """Test that running ninja is possible."""
172     self.inst.Ninja(self.BOARD)
173     self.assertCommandContains([self.BOARD], cwd=self.CWD)
174
175 class HWLabCommandsTest(cros_build_lib_unittest.RunCommandTestCase):
176   """Test commands related to HWLab tests."""
177
178   def setUp(self):
179     self._build = 'test-build'
180     self._board = 'test-board'
181     self._suite = 'test-suite'
182     self._pool = 'test-pool'
183     self._num = 42
184     self._file_bugs = True
185     self._wait_for_results = False
186     self._priority = 'test-priority'
187     self._timeout_mins = 23
188     self._retry = False
189
190   def testRunHWTestSuiteMinimal(self):
191     """Test RunHWTestSuite without optional arguments."""
192     commands.RunHWTestSuite(self._build, self._suite, self._board, debug=False)
193     self.assertCommandCalled([
194         commands._AUTOTEST_RPC_CLIENT, commands._AUTOTEST_RPC_HOSTNAME,
195         'RunSuite', '--build', 'test-build', '--suite_name', 'test-suite',
196         '--board', 'test-board'
197     ], error_code_ok=True)
198
199   def testRunHWTestSuiteMaximal(self):
200     """Test RunHWTestSuite with all arguments."""
201     commands.RunHWTestSuite(self._build, self._suite, self._board,
202                             self._pool, self._num, self._file_bugs,
203                             self._wait_for_results, self._priority,
204                             self._timeout_mins, self._retry, debug=False)
205     self.assertCommandCalled([
206         commands._AUTOTEST_RPC_CLIENT, commands._AUTOTEST_RPC_HOSTNAME,
207         'RunSuite', '--build', 'test-build', '--suite_name', 'test-suite',
208         '--board', 'test-board', '--pool', 'test-pool', '--num', '42',
209         '--file_bugs', 'True', '--no_wait', 'True',
210         '--priority', 'test-priority', '--timeout_mins', '23',
211         '--retry', 'False',
212     ], error_code_ok=True)
213
214   def testRunHWTestSuiteFailure(self):
215     """Test RunHWTestSuite when ERROR is returned."""
216     self.rc.SetDefaultCmdResult(returncode=1)
217     self.assertRaises(commands.TestFailure, commands.RunHWTestSuite,
218                       self._build, self._suite, self._board, debug=False)
219
220   def testRunHWTestSuiteTimedOut(self):
221     """Test RunHWTestSuite when SUITE_TIMEOUT is returned."""
222     self.rc.SetDefaultCmdResult(returncode=4)
223     self.assertRaises(commands.SuiteTimedOut, commands.RunHWTestSuite,
224                       self._build, self._suite, self._board, debug=False)
225
226   def testRunHWTestSuiteInfraFail(self):
227     """Test RunHWTestSuite when INFRA_FAILURE is returned."""
228     self.rc.SetDefaultCmdResult(returncode=3)
229     self.assertRaises(failures_lib.TestLabFailure, commands.RunHWTestSuite,
230                       self._build, self._suite, self._board, debug=False)
231
232
233 class CBuildBotTest(cros_build_lib_unittest.RunCommandTempDirTestCase):
234   """Test general cbuildbot command methods."""
235
236   def setUp(self):
237     self._board = 'test-board'
238     self._buildroot = self.tempdir
239     self._overlays = ['%s/src/third_party/chromiumos-overlay' % self._buildroot]
240     self._chroot = os.path.join(self._buildroot, 'chroot')
241     os.makedirs(os.path.join(self._buildroot, '.repo'))
242
243   def testGenerateStackTraces(self):
244     """Test if we can generate stack traces for minidumps."""
245     os.makedirs(os.path.join(self._chroot, 'tmp'))
246     dump_file = os.path.join(self._chroot, 'tmp', 'test.dmp')
247     dump_file_dir, dump_file_name = os.path.split(dump_file)
248     ret = [(dump_file_dir, [''], [dump_file_name])]
249     with mock.patch('os.walk', return_value=ret):
250       test_results_dir = os.path.join(self.tempdir, 'test_results')
251       commands.GenerateStackTraces(self._buildroot, self._board,
252                                    test_results_dir, self.tempdir, True)
253       self.assertCommandContains(['minidump_stackwalk'])
254
255   def testUprevAllPackages(self):
256     """Test if we get None in revisions.pfq indicating Full Builds."""
257     commands.UprevPackages(self._buildroot, [self._board], self._overlays)
258     self.assertCommandContains(['--boards=%s' % self._board, 'commit'])
259
260   def testVerifyBinpkgMissing(self):
261     """Test case where binpkg is missing."""
262     self.rc.AddCmdResult(partial_mock.ListRegex(r'emerge'),
263         output='\n[ebuild] %s' % constants.CHROME_CP)
264     self.assertRaises(commands.MissingBinpkg, commands.VerifyBinpkg,
265         self._buildroot, self._board, constants.CHROME_CP)
266
267   def testVerifyBinpkgPresent(self):
268     """Test case where binpkg is present."""
269     self.rc.AddCmdResult(partial_mock.ListRegex(r'emerge'),
270         output='\n[binary] %s' % constants.CHROME_CP)
271     commands.VerifyBinpkg(self._buildroot, self._board, constants.CHROME_CP)
272
273   def testVerifyChromeNotInstalled(self):
274     """Test case where Chrome is not installed at all."""
275     commands.VerifyBinpkg(self._buildroot, self._board, constants.CHROME_CP)
276
277   def testBuild(self, default=False, **kwargs):
278     """Base case where Build is called with minimal options."""
279     kwargs.setdefault('build_autotest', default)
280     kwargs.setdefault('usepkg', default)
281     kwargs.setdefault('chrome_binhost_only', default)
282     kwargs.setdefault('skip_chroot_upgrade', default)
283     commands.Build(buildroot=self._buildroot, board='x86-generic', **kwargs)
284     self.assertCommandContains(['./build_packages'])
285
286   def testGetFirmwareVersions(self):
287     self.rc.SetDefaultCmdResult(output='''
288
289 flashrom(8): a273d7fd6663c665176159496bc014ff */build/nyan/usr/sbin/flashrom
290              ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, BuildID[sha1]=61d8a9676e433414fb0e22fa819b55be86329e44, stripped
291
292
293 BIOS image:   4aba4c07a65b7bf82d72d8ed892f5dc5 */build/nyan/tmp/portage/chromeos-base/chromeos-firmware-nyan-0.0.1-r20/work/chromeos-firmware-nyan-0.0.1/.dist/nyan_fw_5771.10.0.tbz2/image.bin
294 BIOS version: Google_Nyan.5771.10.0
295 EC image:     7b6bb5035fa8101b41c954bce5250dae */build/nyan/tmp/portage/chromeos-base/chromeos-firmware-nyan-0.0.1-r20/work/chromeos-firmware-nyan-0.0.1/.dist/nyan_ec_5771.10.0.tbz2/ec.bin
296 EC version:   nyan_v1.1.1782-23f1337
297
298 Package Content:
299 d7124c9a2680ff57f1c7d6521ac5ef8c *./mosys
300 ad9520c70add670d8f2770a2a3c4115a *./gbb_utility
301 7b6bb5035fa8101b41c954bce5250dae *./ec.bin
302 a273d7fd6663c665176159496bc014ff *./flashrom
303 d149f6413749ca6a0edddd52926f95ca *./dump_fmap
304 5bfe13d9b7fef1dfd9d3dac185f94994 *./crossystem
305 3c3a99346d1ca1273cbcd86c104851ff *./shflags
306 4aba4c07a65b7bf82d72d8ed892f5dc5 *./bios.bin
307 2a484f3e107bf27a4d1068e03e74803c *./common.sh
308 995a97518f90541d37c3f57a336d37db *./vpd
309 b9270e726180af1ed59077d1ab2fc688 *./crosfw.sh
310 f6b0b80d5f2d9a2fb41ebb6e2cee7ad8 *./updater4.sh
311 4363fcfd6849b2ab1a7320b1c98a11f2 *./crosutil.sh
312 ''')
313     build_sbin = os.path.join(self._buildroot, constants.DEFAULT_CHROOT_DIR,
314                               'build', self._board, 'usr', 'sbin')
315     osutils.Touch(os.path.join(build_sbin, 'chromeos-firmwareupdate'),
316                   makedirs=True)
317     result = commands.GetFirmwareVersions(self._buildroot, self._board)
318     versions = ('Google_Nyan.5771.10.0', 'nyan_v1.1.1782-23f1337')
319     self.assertEquals(result, versions)
320
321   def testBuildMaximum(self):
322     """Base case where Build is called with all options (except extra_env)."""
323     self.testBuild(default=True)
324
325   def testBuildWithEnv(self):
326     """Case where Build is called with a custom environment."""
327     extra_env = {'A': 'Av', 'B': 'Bv'}
328     self.testBuild(extra_env=extra_env)
329     self.assertCommandContains(['./build_packages'], extra_env=extra_env)
330
331   def testGenerateSymbols(self):
332     """Test GenerateBreakpadSymbols Command."""
333     commands.GenerateBreakpadSymbols(self.tempdir, self._board, False)
334     self.assertCommandContains(['--board=%s' % self._board])
335
336   @mock.patch('chromite.scripts.upload_symbols.UploadSymbols')
337   def testUploadSymbols(self, sym_mock, official=False, cnt=None):
338     """Test UploadSymbols Command."""
339     sym_mock.side_effect = [0]
340     commands.UploadSymbols(self.tempdir, self._board, official, cnt, None)
341     self.assertEquals(sym_mock.call_count, 1)
342     _, kwargs = sym_mock.call_args
343     self.assertEquals(kwargs['official'], official)
344     self.assertEquals(kwargs['upload_limit'], cnt)
345
346   def testOfficialUploadSymbols(self):
347     """Test uploading symbols for official builds"""
348     # Seems pylint can't grasp the @mock.patch decorator.
349     # pylint: disable=E1120
350     self.testUploadSymbols(official=True)
351
352   def testLimitUploadSymbols(self):
353     """Test uploading a limited number of symbols"""
354     # Seems pylint can't grasp the @mock.patch decorator.
355     # pylint: disable=E1120
356     self.testUploadSymbols(cnt=10)
357
358   def testPushImages(self):
359     """Test PushImages Command."""
360     m = self.PatchObject(pushimage, 'PushImage')
361     commands.PushImages(self._board, 'gs://foo/R34-1234.0.0', False, None)
362     self.assertEqual(m.call_count, 1)
363
364   def testBuildImage(self):
365     """Test Basic BuildImage Command."""
366     commands.BuildImage(self._buildroot, self._board, None)
367     self.assertCommandContains(['./build_image'])
368
369   def testGenerateAuZip(self):
370     """Test Basic generate_au_zip Command."""
371     with mock.patch.object(git, 'ReinterpretPathForChroot',
372                            side_effect=lambda x: x):
373       commands.GenerateAuZip(self._buildroot, '/tmp/taco', None)
374     self.assertCommandContains(['./build_library/generate_au_zip.py'])
375
376   def testTestAuZip(self):
377     """Test Basic generate_au_zip Command."""
378     commands.TestAuZip(self._buildroot, '/tmp/taco', None)
379     self.assertCommandContains(['./build_library/test_au_zip.py'])
380
381   def testCompleteBuildImage(self):
382     """Test Complete BuildImage Command."""
383     images_to_build = ['bob', 'carol', 'ted', 'alice']
384     commands.BuildImage(self._buildroot, self._board, images_to_build,
385         rootfs_verification=False, extra_env={'LOVE': 'free'},
386         disk_layout='2+2', version='1969')
387     self.assertCommandContains(['./build_image'])
388
389   def _TestChromeLKGM(self, chrome_revision):
390     """Helper method for testing the GetChromeLKGM method."""
391     chrome_lkgm = '3322.0.0'
392     url = '%s/+/%s/%s?format=text' % (
393         constants.CHROMIUM_SRC_PROJECT,
394         chrome_revision or 'refs/heads/master',
395         constants.PATH_TO_CHROME_LKGM)
396     with mock.patch.object(
397         gob_util, 'FetchUrl',
398         return_value=StringIO(base64.b64encode(chrome_lkgm))) as patcher:
399       self.assertEqual(chrome_lkgm, commands.GetChromeLKGM(chrome_revision))
400       patcher.assert_called_with(constants.EXTERNAL_GOB_HOST, url)
401
402   def testChromeLKGM(self):
403     """Verifies that we can get the chrome lkgm without a chrome revision."""
404     self._TestChromeLKGM(None)
405
406   def testChromeLKGMWithRevision(self):
407     """Verifies that we can get the chrome lkgm with a chrome revision."""
408     self._TestChromeLKGM('deadbeef' * 5)
409
410   def testAbortCQHWTests(self):
411     commands.AbortCQHWTests('my-version', debug=False)
412     self.assertCommandContains(['cp'])
413     self.assertCommandContains(['-i', 'paladin/my-version'])
414
415   def testHWTestsAborted(self, aborted=True):
416     self.PatchObject(gs.GSContext, 'Exists', return_value=aborted)
417     self.assertEqual(commands.HaveCQHWTestsBeenAborted('my-version'), aborted)
418
419   def testHWTestsNotAborted(self):
420     self.testHWTestsAborted(aborted=False)
421
422
423 class BuildTarballTests(cros_build_lib_unittest.RunCommandTempDirTestCase):
424   """Tests related to BuildAUTestTarball."""
425
426   def setUp(self):
427     self._buildroot = os.path.join(self.tempdir, 'buildroot')
428     os.makedirs(self._buildroot)
429     self._board = 'test-board'
430
431   def testBuildAUTestTarball(self):
432     """Tests that our call to generate an au test tarball is correct."""
433     tarball_dir = self.tempdir
434     archive_url = 'gs://mytest/path/version'
435     with mock.patch.object(commands, 'BuildTarball') as m:
436       tarball_path = commands.BuildAUTestTarball(
437           self._buildroot, self._board, tarball_dir, 'R26-3928.0.0',
438           archive_url)
439       m.assert_called_once_with(self._buildroot, ['autotest/au_control_files'],
440                                 os.path.join(tarball_dir, 'au_control.tar.bz2'),
441                                 cwd=tarball_dir)
442
443       self.assertEquals(os.path.join(tarball_dir, 'au_control.tar.bz2'),
444                         tarball_path)
445
446     # Full release test with partial args defined.
447     self.assertCommandContains(['site_utils/autoupdate/full_release_test.py',
448                                 '--archive_url', archive_url, '3928.0.0',
449                                 self._board])
450
451
452 class UnmockedTests(cros_test_lib.TempDirTestCase):
453   """Test cases which really run tests, instead of using mocks."""
454
455   def testListFaliedTests(self):
456     """Tests if we can list failed tests."""
457     test_report_1 = """
458 /tmp/taco/taste_tests/all/results-01-has_salsa              [  PASSED  ]
459 /tmp/taco/taste_tests/all/results-01-has_salsa/has_salsa    [  PASSED  ]
460 /tmp/taco/taste_tests/all/results-02-has_cheese             [  FAILED  ]
461 /tmp/taco/taste_tests/all/results-02-has_cheese/has_cheese  [  FAILED  ]
462 /tmp/taco/taste_tests/all/results-02-has_cheese/has_cheese   FAIL: No cheese.
463 """
464     test_report_2 = """
465 /tmp/taco/verify_tests/all/results-01-has_salsa              [  PASSED  ]
466 /tmp/taco/verify_tests/all/results-01-has_salsa/has_salsa    [  PASSED  ]
467 /tmp/taco/verify_tests/all/results-02-has_cheese             [  PASSED  ]
468 /tmp/taco/verify_tests/all/results-02-has_cheese/has_cheese  [  PASSED  ]
469 """
470     results_path = os.path.join(self.tempdir, 'tmp/taco')
471     os.makedirs(results_path)
472     # Create two reports with the same content to test that we don't
473     # list the same test twice.
474     osutils.WriteFile(
475         os.path.join(results_path, 'taste_tests', 'all', 'test_report.log'),
476         test_report_1, makedirs=True)
477     osutils.WriteFile(
478         os.path.join(results_path, 'taste_tests', 'failed', 'test_report.log'),
479         test_report_1, makedirs=True)
480     osutils.WriteFile(
481         os.path.join(results_path, 'verify_tests', 'all', 'test_report.log'),
482         test_report_2, makedirs=True)
483
484     self.assertEquals(
485         commands.ListFailedTests(results_path),
486         [('has_cheese', 'taste_tests/all/results-02-has_cheese')])
487
488   def testArchiveTestResults(self):
489     """Test if we can archive a test results dir."""
490     test_results_dir = 'tmp/taco'
491     results_path = os.path.join(self.tempdir, 'chroot', test_results_dir)
492     archive_dir = os.path.join(self.tempdir, 'archived_taco')
493     os.makedirs(results_path)
494     os.makedirs(archive_dir)
495     # File that should be archived.
496     osutils.Touch(os.path.join(results_path, 'foo.txt'))
497     # Flies that should be ignored.
498     osutils.Touch(os.path.join(results_path,
499                                'chromiumos_qemu_disk.bin.foo'))
500     os.symlink('/src/foo', os.path.join(results_path, 'taco_link'))
501     commands.ArchiveTestResults(results_path, archive_dir)
502     self.assertExists(os.path.join(archive_dir, 'foo.txt'))
503     self.assertNotExists(
504         os.path.join(archive_dir, 'chromiumos_qemu_disk.bin.foo'))
505     self.assertNotExists(os.path.join(archive_dir, 'taco_link'))
506
507   def testBuildFirmwareArchive(self):
508     """Verifies that firmware archiver includes proper files"""
509     # Assorted set of file names, some of which are supposed to be included in
510     # the archive.
511     fw_files = (
512       'dts/emeraldlake2.dts',
513       'image-link.rw.bin',
514       'nv_image-link.bin',
515       'pci8086,0166.rom',
516       'seabios.cbfs',
517       'u-boot.elf',
518       'u-boot_netboot.bin',
519       'updater-link.rw.sh',
520       'x86-memtest')
521     # Files which should be included in the archive.
522     fw_archived_files = fw_files + ('dts/',)
523     board = 'link'
524     fw_test_root = os.path.join(self.tempdir, os.path.basename(__file__))
525     fw_files_root = os.path.join(fw_test_root,
526                                  'chroot/build/%s/firmware' % board)
527     # Generate a representative set of files produced by a typical build.
528     cros_test_lib.CreateOnDiskHierarchy(fw_files_root, fw_files)
529     # Create an archive from the simulated firmware directory
530     tarball = os.path.join(
531         fw_test_root,
532         commands.BuildFirmwareArchive(fw_test_root, board, fw_test_root))
533     # Verify the tarball contents.
534     cros_test_lib.VerifyTarball(tarball, fw_archived_files)
535
536   def testGenerateHtmlIndexTuple(self):
537     """Verifies GenerateHtmlIndex gives us something sane (input: tuple)"""
538     index = os.path.join(self.tempdir, 'index.html')
539     files = ('file1', 'monkey tree', 'flying phone',)
540     commands.GenerateHtmlIndex(index, files)
541     html = osutils.ReadFile(index)
542     for f in files:
543       # TODO(build): Use assertIn w/python-2.7.
544       self.assertTrue('>%s</a>' % f in html)
545
546   def testGenerateHtmlIndexTupleDupe(self):
547     """Verifies GenerateHtmlIndex gives us something unique (input: tuple)"""
548     index = os.path.join(self.tempdir, 'index.html')
549     files = ('file1', 'file1', 'file1',)
550     commands.GenerateHtmlIndex(index, files)
551     html = osutils.ReadFile(index)
552     self.assertEqual(html.count('>file1</a>'), 1)
553
554   def testGenerateHtmlIndexTuplePretty(self):
555     """Verifies GenerateHtmlIndex gives us something pretty (input: tuple)"""
556     index = os.path.join(self.tempdir, 'index.html')
557     files = ('..|up', 'f.txt|MY FILE', 'm.log|MONKEY', 'b.bin|Yander',)
558     commands.GenerateHtmlIndex(index, files)
559     html = osutils.ReadFile(index)
560     for f in files:
561       a = f.split('|')
562       # TODO(build): Use assertIn w/python-2.7.
563       self.assertTrue('href="%s"' % a[0] in html)
564       self.assertTrue('>%s</a>' % a[1] in html)
565
566   def testGenerateHtmlIndexDir(self):
567     """Verifies GenerateHtmlIndex gives us something sane (input: dir)"""
568     index = os.path.join(self.tempdir, 'index.html')
569     files = ('a', 'b b b', 'c', 'dalsdkjfasdlkf',)
570     simple_dir = os.path.join(self.tempdir, 'dir')
571     for f in files:
572       osutils.Touch(os.path.join(simple_dir, f), makedirs=True)
573     commands.GenerateHtmlIndex(index, files)
574     html = osutils.ReadFile(index)
575     for f in files:
576       # TODO(build): Use assertIn w/python-2.7.
577       self.assertTrue('>%s</a>' % f in html)
578
579   def testGenerateHtmlIndexFile(self):
580     """Verifies GenerateHtmlIndex gives us something sane (input: file)"""
581     index = os.path.join(self.tempdir, 'index.html')
582     files = ('a.tgz', 'b b b.txt', 'c', 'dalsdkjfasdlkf',)
583     filelist = os.path.join(self.tempdir, 'listing')
584     osutils.WriteFile(filelist, '\n'.join(files))
585     commands.GenerateHtmlIndex(index, filelist)
586     html = osutils.ReadFile(index)
587     for f in files:
588       # TODO(build): Use assertIn w/python-2.7.
589       self.assertTrue('>%s</a>' % f in html)
590
591   def testArchiveGeneration(self):
592     """Verifies BuildStandaloneImageArchive produces correct archives"""
593     image_dir = os.path.join(self.tempdir, 'inputs')
594     archive_dir = os.path.join(self.tempdir, 'outputs')
595     files = ('a.bin', 'aa', 'b b b', 'c', 'dalsdkjfasdlkf',)
596     osutils.SafeMakedirs(image_dir)
597     osutils.SafeMakedirs(archive_dir)
598     for f in files:
599       osutils.Touch(os.path.join(image_dir, f))
600
601     # Check specifying tar functionality.
602     artifact = {'paths': ['a.bin'], 'output': 'a.tar.gz', 'archive': 'tar',
603                 'compress':'gz'}
604     path = commands.BuildStandaloneArchive(archive_dir, image_dir, artifact)
605     self.assertEquals(path, ['a.tar.gz'])
606     cros_test_lib.VerifyTarball(os.path.join(archive_dir, path[0]),
607                                 ['a.bin'])
608
609     # Check multiple input files.
610     artifact = {'paths': ['a.bin', 'aa'], 'output': 'aa.tar.gz',
611                 'archive': 'tar', 'compress': 'gz'}
612     path = commands.BuildStandaloneArchive(archive_dir, image_dir, artifact)
613     self.assertEquals(path, ['aa.tar.gz'])
614     cros_test_lib.VerifyTarball(os.path.join(archive_dir, path[0]),
615                                 ['a.bin', 'aa'])
616
617     # Check zip functionality.
618     artifact = {'paths': ['a.bin'], 'archive': 'zip'}
619     path = commands.BuildStandaloneArchive(archive_dir, image_dir, artifact)
620     self.assertEquals(path, ['a.zip'])
621     self.assertExists(os.path.join(archive_dir, path[0]))
622
623
624 class ImageTestCommandsTest(cros_build_lib_unittest.RunCommandTestCase):
625   """Test commands related to ImageTest tests."""
626
627   def setUp(self):
628     self._build = 'test-build'
629     self._board = 'test-board'
630     self._image_dir = 'image-dir'
631     self._result_dir = 'result-dir'
632     self.PatchObject(git, 'ReinterpretPathForChroot',
633                      side_effect=lambda x: x)
634
635   def testRunTestImage(self):
636     """Verifies RunTestImage calls into test-image script properly."""
637     commands.RunTestImage(self._build, self._board, self._image_dir,
638                           self._result_dir)
639     self.assertCommandContains(
640         [
641           'sudo', '--',
642           os.path.join(self._build, 'chromite', 'bin', 'test_image'),
643           '--board', self._board,
644           '--test_results_root',
645           cros_build_lib.ToChrootPath(self._result_dir),
646           cros_build_lib.ToChrootPath(self._image_dir),
647         ],
648         enter_chroot=True,
649     )
650
651
652 if __name__ == '__main__':
653   cros_test_lib.main()