blob: ee72adfb0b6c77951ae928326516fb10d2924933 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
Nam T. Nguyenf3816362014-06-13 09:26:27 -07002# Copyright 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"""Script to mount a built image and run tests on it."""
7
Mike Frysinger383367e2014-09-16 15:06:17 -04008from __future__ import print_function
9
Nam T. Nguyenf3816362014-06-13 09:26:27 -070010import os
Nam T. Nguyenf3816362014-06-13 09:26:27 -070011import unittest
12
Aviv Keshetb7519e12016-10-04 00:50:00 -070013from chromite.lib import constants
Nam T. Nguyenf3816362014-06-13 09:26:27 -070014from chromite.lib import commandline
Mike Nicholsa8e8f242019-09-09 14:10:29 -060015from chromite.lib import image_lib
Nam T. Nguyenc8ef7742015-06-01 13:34:35 -070016from chromite.lib import image_test_lib
Nam T. Nguyenf3816362014-06-13 09:26:27 -070017from chromite.lib import osutils
Gilad Arnold1c8eda52015-05-04 22:32:38 -070018from chromite.lib import path_util
Nam T. Nguyenf3816362014-06-13 09:26:27 -070019
20
21def ParseArgs(args):
22 """Return parsed commandline arguments."""
23
Mike Frysinger99b12fd2018-09-05 18:14:26 -040024 parser = commandline.ArgumentParser(description=__doc__)
Nam T. Nguyenf3816362014-06-13 09:26:27 -070025 parser.add_argument('--test_results_root', type='path',
26 help='Directory to store test results')
27 parser.add_argument('--board', type=str, help='Board (wolf, beaglebone...)')
Mike Frysinger99b12fd2018-09-05 18:14:26 -040028 parser.add_argument('image', type='path',
Nam T. Nguyenf3816362014-06-13 09:26:27 -070029 help='Image directory (or file) with mount_image.sh and '
30 'umount_image.sh')
Mike Frysinger6dd14f42017-10-18 18:33:35 -040031
32 parser.add_argument('-l', '--list', default=False, action='store_true',
33 help='List all the available tests')
34 parser.add_argument('tests', nargs='*', metavar='test',
35 help='Specific tests to run (default runs all)')
36
Nam T. Nguyenf3816362014-06-13 09:26:27 -070037 opts = parser.parse_args(args)
38 opts.Freeze()
39 return opts
40
41
42def FindImage(image_path):
43 """Return the path to the image file.
44
45 Args:
46 image_path: A path to the image file, or a directory containing the base
47 image.
48
49 Returns:
50 ImageFileAndMountScripts containing absolute paths to the image,
51 the mount and umount invocation commands
52 """
53
54 if os.path.isdir(image_path):
55 # Assume base image.
56 image_file = os.path.join(image_path, constants.BASE_IMAGE_NAME + '.bin')
57 if not os.path.exists(image_file):
Nam T. Nguyend5e4cfb2014-07-23 14:47:14 -070058 raise ValueError('Cannot find base image %s' % image_file)
Nam T. Nguyenf3816362014-06-13 09:26:27 -070059 elif os.path.isfile(image_path):
60 image_file = image_path
61 else:
62 raise ValueError('%s is neither a directory nor a file' % image_path)
63
64 return image_file
65
66
67def main(args):
68 opts = ParseArgs(args)
69
70 # Build up test suites.
71 loader = unittest.TestLoader()
Nam T. Nguyenc8ef7742015-06-01 13:34:35 -070072 loader.suiteClass = image_test_lib.ImageTestSuite
Nam T. Nguyenf3816362014-06-13 09:26:27 -070073 # We use a different prefix here so that unittest DO NOT pick up the
74 # image tests automatically because they depend on a proper environment.
75 loader.testMethodPrefix = 'Test'
Mike Frysinger6dd14f42017-10-18 18:33:35 -040076 tests_namespace = 'chromite.cros.test.image_test'
77 if opts.tests:
78 tests = ['%s.%s' % (tests_namespace, x) for x in opts.tests]
79 else:
80 tests = (tests_namespace,)
81 all_tests = loader.loadTestsFromNames(tests)
82
83 # If they just want to see the lists of tests, show them now.
84 if opts.list:
85 def _WalkSuite(suite):
86 for test in suite:
87 if isinstance(test, unittest.BaseTestSuite):
88 for result in _WalkSuite(test):
89 yield result
90 else:
91 yield (test.id()[len(tests_namespace) + 1:],
92 test.shortDescription() or '')
93
94 test_list = list(_WalkSuite(all_tests))
95 maxlen = max(len(x[0]) for x in test_list)
96 for name, desc in test_list:
97 print('%-*s %s' % (maxlen, name, desc))
98 return
Nam T. Nguyenf3816362014-06-13 09:26:27 -070099
100 # Run them in the image directory.
Nam T. Nguyenc8ef7742015-06-01 13:34:35 -0700101 runner = image_test_lib.ImageTestRunner()
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700102 runner.SetBoard(opts.board)
103 runner.SetResultDir(opts.test_results_root)
Mike Frysinger99b12fd2018-09-05 18:14:26 -0400104 image_file = FindImage(opts.image)
Gilad Arnold1c8eda52015-05-04 22:32:38 -0700105 tmp_in_chroot = path_util.FromChrootPath('/tmp')
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700106 with osutils.TempDir(base_dir=tmp_in_chroot) as temp_dir:
Mike Nicholsa8e8f242019-09-09 14:10:29 -0600107 with image_lib.LoopbackPartitions(image_file, temp_dir) as image:
108 # Due to the lack of mount context, we mount the partitions
109 # but do not reference directly. This will be removed with the
110 # submission of http://crrev/c/1795578
111 _ = image.Mount((constants.PART_ROOT_A,))[0]
112 _ = image.Mount((constants.PART_STATE,))[0]
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700113 with osutils.ChdirContext(temp_dir):
Mike Frysinger3e046612017-10-18 17:19:23 -0400114 result = runner.run(all_tests)
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700115
116 if result and not result.wasSuccessful():
117 return 1
118 return 0