diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/oe-selftest | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/scripts/oe-selftest b/scripts/oe-selftest index 91e2dd2824..9679962ec0 100755 --- a/scripts/oe-selftest +++ b/scripts/oe-selftest | |||
@@ -30,6 +30,7 @@ import sys | |||
30 | import unittest | 30 | import unittest |
31 | import logging | 31 | import logging |
32 | import argparse | 32 | import argparse |
33 | import subprocess | ||
33 | 34 | ||
34 | sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/lib') | 35 | sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/lib') |
35 | import scriptpath | 36 | import scriptpath |
@@ -70,6 +71,7 @@ def get_args_parser(): | |||
70 | group.add_argument('--run-all-tests', required=False, action="store_true", dest="run_all_tests", default=False, help='Run all (unhidden) tests') | 71 | group.add_argument('--run-all-tests', required=False, action="store_true", dest="run_all_tests", default=False, help='Run all (unhidden) tests') |
71 | group.add_argument('--list-modules', required=False, action="store_true", dest="list_modules", default=False, help='List all available test modules.') | 72 | group.add_argument('--list-modules', required=False, action="store_true", dest="list_modules", default=False, help='List all available test modules.') |
72 | group.add_argument('--list-classes', required=False, action="store_true", dest="list_allclasses", default=False, help='List all available test classes.') | 73 | group.add_argument('--list-classes', required=False, action="store_true", dest="list_allclasses", default=False, help='List all available test classes.') |
74 | parser.add_argument('--coverage', action="store_true", help="Run code coverage when testing") | ||
73 | return parser | 75 | return parser |
74 | 76 | ||
75 | 77 | ||
@@ -197,6 +199,42 @@ def main(): | |||
197 | if not preflight_check(): | 199 | if not preflight_check(): |
198 | return 1 | 200 | return 1 |
199 | 201 | ||
202 | if args.coverage: | ||
203 | try: | ||
204 | # check if user can do coverage | ||
205 | import coverage | ||
206 | log.info("Coverage is enabled") | ||
207 | except: | ||
208 | log.warn(("python coverage is not installed\n", | ||
209 | "Make sure you are also coverage takes into account sub-process\n", | ||
210 | "More info on https://pypi.python.org/pypi/coverage\n")) | ||
211 | |||
212 | # In case the user has not set the variable COVERAGE_PROCESS_START, | ||
213 | # create a default one and export it. The COVERAGE_PROCESS_START | ||
214 | # value indicates where the coverage configuration file resides | ||
215 | # More info on https://pypi.python.org/pypi/coverage | ||
216 | coverage_process_start = os.environ.get('COVERAGE_PROCESS_START') | ||
217 | if not coverage_process_start: | ||
218 | builddir = os.environ.get("BUILDDIR") | ||
219 | coveragerc = "%s/.coveragerc" % builddir | ||
220 | data_file = "%s/.coverage." % builddir | ||
221 | data_file += ((args.run_tests and ".".join(args.run_tests)) or | ||
222 | (args.run_all_tests and ".all_tests") or '') | ||
223 | if os.path.isfile(data_file): | ||
224 | os.remove(data_file) | ||
225 | with open(coveragerc, 'w') as cps: | ||
226 | cps.write("[run]\n") | ||
227 | cps.write("data_file = %s\n" % data_file) | ||
228 | cps.write("branch = True\n") | ||
229 | # Measure just BBLAYERS, scripts and bitbake folders | ||
230 | cps.write("source = \n") | ||
231 | for layer in get_bb_var('BBLAYERS').split(): | ||
232 | cps.write(" %s\n" % layer) | ||
233 | cps.write(" %s\n" % os.path.dirname(os.path.realpath(__file__))) | ||
234 | cps.write(" %s\n" % os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))),'bitbake')) | ||
235 | |||
236 | coverage_process_start = os.environ["COVERAGE_PROCESS_START"] = coveragerc | ||
237 | |||
200 | testslist = get_tests(exclusive_modules=(args.run_tests or []), include_hidden=False) | 238 | testslist = get_tests(exclusive_modules=(args.run_tests or []), include_hidden=False) |
201 | suite = unittest.TestSuite() | 239 | suite = unittest.TestSuite() |
202 | loader = unittest.TestLoader() | 240 | loader = unittest.TestLoader() |
@@ -216,6 +254,29 @@ def main(): | |||
216 | add_include() | 254 | add_include() |
217 | result = runner.run(suite) | 255 | result = runner.run(suite) |
218 | log.info("Finished") | 256 | log.info("Finished") |
257 | |||
258 | if args.coverage: | ||
259 | with open(coverage_process_start) as ccf: | ||
260 | log.info("Coverage configuration file (%s)" % coverage_process_start) | ||
261 | log.info("===========================") | ||
262 | log.info("\n%s" % "".join(ccf.readlines())) | ||
263 | |||
264 | try: | ||
265 | # depending on the version, coverage command is named 'python-coverage' or 'coverage', | ||
266 | # where the latter is for newer versions | ||
267 | coverage_cmd = "python-coverage" | ||
268 | subprocess.check_call(coverage_cmd, stderr=subprocess.PIPE, shell=True) | ||
269 | except subprocess.CalledProcessError: | ||
270 | coverage_cmd = "coverage" | ||
271 | pass | ||
272 | |||
273 | log.info("Coverage Report") | ||
274 | log.info("===============") | ||
275 | p = subprocess.Popen("%s report" % coverage_cmd, shell=True, | ||
276 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) | ||
277 | cov_output, cov_err = p.communicate() | ||
278 | log.info("\n%s" % cov_output) | ||
279 | |||
219 | if result.wasSuccessful(): | 280 | if result.wasSuccessful(): |
220 | return 0 | 281 | return 0 |
221 | else: | 282 | else: |