blob: f855812e4989b2f33d19ae77df155d4286d81aaa [file] [log] [blame]
Nam T. Nguyenf3816362014-06-13 09:26:27 -07001# Copyright 2014 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Script to mount a built image and run tests on it."""
6
Nam T. Nguyenf3816362014-06-13 09:26:27 -07007import os
Nam T. Nguyenf3816362014-06-13 09:26:27 -07008import unittest
9
Nam T. Nguyenf3816362014-06-13 09:26:27 -070010from chromite.lib import commandline
Mike Frysinger807d8282022-04-28 22:45:17 -040011from chromite.lib import constants
Mike Nicholsa8e8f242019-09-09 14:10:29 -060012from chromite.lib import image_lib
Nam T. Nguyenc8ef7742015-06-01 13:34:35 -070013from chromite.lib import image_test_lib
Nam T. Nguyenf3816362014-06-13 09:26:27 -070014from chromite.lib import osutils
Gilad Arnold1c8eda52015-05-04 22:32:38 -070015from chromite.lib import path_util
Nam T. Nguyenf3816362014-06-13 09:26:27 -070016
17
18def ParseArgs(args):
Alex Klein1699fab2022-09-08 08:46:06 -060019 """Return parsed commandline arguments."""
Nam T. Nguyenf3816362014-06-13 09:26:27 -070020
Alex Klein1699fab2022-09-08 08:46:06 -060021 parser = commandline.ArgumentParser(description=__doc__)
22 parser.add_argument(
23 "--test_results_root",
24 type="path",
25 help="Directory to store test results",
26 )
27 parser.add_argument("--board", type=str, help="Board (wolf, beaglebone...)")
28 parser.add_argument(
29 "image",
30 type="path",
31 help="Image directory (or file) with mount_image.sh and "
32 "umount_image.sh",
33 )
Mike Frysinger6dd14f42017-10-18 18:33:35 -040034
Alex Klein1699fab2022-09-08 08:46:06 -060035 parser.add_argument(
36 "-l",
37 "--list",
38 default=False,
39 action="store_true",
40 help="List all the available tests",
41 )
42 parser.add_argument(
43 "tests",
44 nargs="*",
45 metavar="test",
46 help="Specific tests to run (default runs all)",
47 )
Mike Frysinger6dd14f42017-10-18 18:33:35 -040048
Alex Klein1699fab2022-09-08 08:46:06 -060049 opts = parser.parse_args(args)
50 opts.Freeze()
51 return opts
Nam T. Nguyenf3816362014-06-13 09:26:27 -070052
53
54def FindImage(image_path):
Alex Klein1699fab2022-09-08 08:46:06 -060055 """Return the path to the image file.
Nam T. Nguyenf3816362014-06-13 09:26:27 -070056
Alex Klein1699fab2022-09-08 08:46:06 -060057 Args:
58 image_path: A path to the image file, or a directory containing the base
59 image.
Nam T. Nguyenf3816362014-06-13 09:26:27 -070060
Alex Klein1699fab2022-09-08 08:46:06 -060061 Returns:
62 ImageFileAndMountScripts containing absolute paths to the image,
63 the mount and umount invocation commands
64 """
Nam T. Nguyenf3816362014-06-13 09:26:27 -070065
Alex Klein1699fab2022-09-08 08:46:06 -060066 if os.path.isdir(image_path):
67 # Assume base image.
68 image_file = os.path.join(
69 image_path, constants.BASE_IMAGE_NAME + ".bin"
70 )
71 if not os.path.exists(image_file):
72 raise ValueError("Cannot find base image %s" % image_file)
73 elif os.path.isfile(image_path):
74 image_file = image_path
75 else:
76 raise ValueError("%s is neither a directory nor a file" % image_path)
Nam T. Nguyenf3816362014-06-13 09:26:27 -070077
Alex Klein1699fab2022-09-08 08:46:06 -060078 return image_file
Nam T. Nguyenf3816362014-06-13 09:26:27 -070079
80
81def main(args):
Alex Klein1699fab2022-09-08 08:46:06 -060082 opts = ParseArgs(args)
Nam T. Nguyenf3816362014-06-13 09:26:27 -070083
Alex Klein1699fab2022-09-08 08:46:06 -060084 # Build up test suites.
85 loader = unittest.TestLoader()
86 loader.suiteClass = image_test_lib.ImageTestSuite
87 # We use a different prefix here so that unittest DO NOT pick up the
88 # image tests automatically because they depend on a proper environment.
89 loader.testMethodPrefix = "Test"
90 tests_namespace = "chromite.cros.test.image_test"
91 if opts.tests:
92 tests = ["%s.%s" % (tests_namespace, x) for x in opts.tests]
93 else:
94 tests = (tests_namespace,)
95 all_tests = loader.loadTestsFromNames(tests)
Mike Frysinger6dd14f42017-10-18 18:33:35 -040096
Alex Klein1699fab2022-09-08 08:46:06 -060097 # If they just want to see the lists of tests, show them now.
98 if opts.list:
Mike Frysinger6dd14f42017-10-18 18:33:35 -040099
Alex Klein1699fab2022-09-08 08:46:06 -0600100 def _WalkSuite(suite):
101 for test in suite:
102 if isinstance(test, unittest.BaseTestSuite):
103 for result in _WalkSuite(test):
104 yield result
105 else:
106 yield (
107 test.id()[len(tests_namespace) + 1 :],
108 test.shortDescription() or "",
109 )
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700110
Alex Klein1699fab2022-09-08 08:46:06 -0600111 test_list = list(_WalkSuite(all_tests))
112 maxlen = max(len(x[0]) for x in test_list)
113 for name, desc in test_list:
114 print("%-*s %s" % (maxlen, name, desc))
115 return
Nam T. Nguyenf3816362014-06-13 09:26:27 -0700116
Alex Klein1699fab2022-09-08 08:46:06 -0600117 # Run them in the image directory.
118 runner = image_test_lib.ImageTestRunner()
119 runner.SetBoard(opts.board)
120 runner.SetResultDir(opts.test_results_root)
121 image_file = FindImage(opts.image)
122 tmp_in_chroot = path_util.FromChrootPath("/tmp")
123 with osutils.TempDir(base_dir=tmp_in_chroot) as temp_dir:
124 with image_lib.LoopbackPartitions(image_file, temp_dir) as image:
125 # Due to the lack of mount context, we mount the partitions
126 # but do not reference directly. This will be removed with the
127 # submission of http://crrev/c/1795578
128 _ = image.Mount((constants.PART_ROOT_A,))[0]
129 _ = image.Mount((constants.PART_STATE,))[0]
130 with osutils.ChdirContext(temp_dir):
131 result = runner.run(all_tests)
132
133 if result and not result.wasSuccessful():
134 return 1
135 return 0