summaryrefslogtreecommitdiffstats
path: root/scripts/yocto-compat-layer.py
diff options
context:
space:
mode:
authorAníbal Limón <anibal.limon@linux.intel.com>2017-02-20 15:12:49 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-03-04 23:18:19 +0000
commit93633edcf84dbf5d97a43cb8d1ebff790a6ab334 (patch)
tree5d6a97536fd882c475b43f76c735d171d5b5df26 /scripts/yocto-compat-layer.py
parent28376f9552087bef93919cc5cf4a8e88a02f6d04 (diff)
downloadpoky-93633edcf84dbf5d97a43cb8d1ebff790a6ab334.tar.gz
yocto-compat-layer.py: Add script to YP Compatible Layer validation
The yocto-compat-layer script serves as a tool to validate the alignament of a layer with YP Compatible Layers Programme [1], is based on an RFC sent to the ML to enable automatic testing of layers [2] that wants to be YP Compatible. The tool takes an layer (or set of layers) via command line option -l and detects what kind of layer is distro, machine or software and then executes a set of tests against the layer in order to validate the compatibility. The tests currently implemented are: common.test_readme: Test if a README file exists in the layer and isn't empty. common.test_parse: Test for execute bitbake -p without errors. common.test_show_environment: Test for execute bitbake -e without errors. common.test_signatures: Test executed in BSP and DISTRO layers to review doesn't comes with recipes that changes the signatures. bsp.test_bsp_defines_machines: Test if a BSP layers has machines configurations. bsp.test_bsp_no_set_machine: Test the BSP layer to doesn't set machine at adding layer. distro.test_distro_defines_distros: Test if a DISTRO layers has distro configurations. distro.test_distro_no_set_distro: Test the DISTRO layer to doesn't set distro at adding layer. Example of usage: $ source oe-init-build-env $ yocto-compat-layer.py LAYER_DIR [YOCTO #10596] [1] https://www.yoctoproject.org/webform/yocto-project-compatible-registration [2] https://lists.yoctoproject.org/pipermail/yocto-ab/2016-October/001801.html (From OE-Core rev: e14596ac33329bc61fe38a6582fa91f76ff5b147) Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/yocto-compat-layer.py')
-rwxr-xr-xscripts/yocto-compat-layer.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/scripts/yocto-compat-layer.py b/scripts/yocto-compat-layer.py
new file mode 100755
index 0000000000..09dc5bf450
--- /dev/null
+++ b/scripts/yocto-compat-layer.py
@@ -0,0 +1,153 @@
1#!/usr/bin/env python3
2
3# Yocto Project compatibility layer tool
4#
5# Copyright (C) 2017 Intel Corporation
6# Released under the MIT license (see COPYING.MIT)
7
8import os
9import sys
10import argparse
11import logging
12import time
13import signal
14import shutil
15import collections
16
17scripts_path = os.path.dirname(os.path.realpath(__file__))
18lib_path = scripts_path + '/lib'
19sys.path = sys.path + [lib_path]
20import scriptutils
21import scriptpath
22scriptpath.add_oe_lib_path()
23scriptpath.add_bitbake_lib_path()
24
25from compatlayer import LayerType, detect_layers, add_layer, get_signatures
26from oeqa.utils.commands import get_bb_vars
27
28PROGNAME = 'yocto-compat-layer'
29DEFAULT_OUTPUT_LOG = '%s-%s.log' % (PROGNAME,
30 time.strftime("%Y%m%d%H%M%S"))
31OUTPUT_LOG_LINK = "%s.log" % PROGNAME
32CASES_PATHS = [os.path.join(os.path.abspath(os.path.dirname(__file__)),
33 'lib', 'compatlayer', 'cases')]
34logger = scriptutils.logger_create(PROGNAME)
35
36def test_layer_compatibility(td, layer):
37 from compatlayer.context import CompatLayerTestContext
38 logger.info("Starting to analyze: %s" % layer['name'])
39 logger.info("----------------------------------------------------------------------")
40
41 tc = CompatLayerTestContext(td=td, logger=logger, layer=layer)
42 tc.loadTests(CASES_PATHS)
43 return tc.runTests()
44
45def main():
46 parser = argparse.ArgumentParser(
47 description="Yocto Project compatibility layer tool",
48 add_help=False)
49 parser.add_argument('layers', metavar='LAYER_DIR', nargs='+',
50 help='Layer to test compatibility with Yocto Project')
51 parser.add_argument('-o', '--output-log',
52 help='Output log default: %s' % DEFAULT_OUTPUT_LOG,
53 action='store', default=DEFAULT_OUTPUT_LOG)
54
55 parser.add_argument('-d', '--debug', help='Enable debug output',
56 action='store_true')
57 parser.add_argument('-q', '--quiet', help='Print only errors',
58 action='store_true')
59
60 parser.add_argument('-h', '--help', action='help',
61 default=argparse.SUPPRESS,
62 help='show this help message and exit')
63
64 args = parser.parse_args()
65
66 fh = logging.FileHandler(args.output_log)
67 fh.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
68 logger.addHandler(fh)
69 if args.debug:
70 logger.setLevel(logging.DEBUG)
71 elif args.quiet:
72 logger.setLevel(logging.ERROR)
73 if os.path.exists(OUTPUT_LOG_LINK):
74 os.unlink(OUTPUT_LOG_LINK)
75 os.symlink(args.output_log, OUTPUT_LOG_LINK)
76
77 if not 'BUILDDIR' in os.environ:
78 logger.error("You must source the environment before run this script.")
79 logger.error("$ source oe-init-build-env")
80 return 1
81 builddir = os.environ['BUILDDIR']
82 bblayersconf = os.path.join(builddir, 'conf', 'bblayers.conf')
83
84 layers = detect_layers(args.layers)
85 if not layers:
86 logger.error("Fail to detect layers")
87 return 1
88
89 logger.info("Detected layers:")
90 for layer in layers:
91 if layer['type'] == LayerType.ERROR_BSP_DISTRO:
92 logger.error("%s: Can't be DISTRO and BSP type at the same time."\
93 " The conf/distro and conf/machine folders was found."\
94 % layer['name'])
95 layers.remove(layer)
96 elif layer['type'] == LayerType.ERROR_NO_LAYER_CONF:
97 logger.error("%s: Don't have conf/layer.conf file."\
98 % layer['name'])
99 layers.remove(layer)
100 else:
101 logger.info("%s: %s, %s" % (layer['name'], layer['type'],
102 layer['path']))
103 if not layers:
104 return 1
105
106 shutil.copyfile(bblayersconf, bblayersconf + '.backup')
107 def cleanup_bblayers(signum, frame):
108 shutil.copyfile(bblayersconf + '.backup', bblayersconf)
109 os.unlink(bblayersconf + '.backup')
110 signal.signal(signal.SIGTERM, cleanup_bblayers)
111 signal.signal(signal.SIGINT, cleanup_bblayers)
112
113 td = {}
114 results = collections.OrderedDict()
115
116 logger.info('')
117 logger.info('Getting initial bitbake variables ...')
118 td['bbvars'] = get_bb_vars()
119 logger.info('Getting initial signatures ...')
120 td['builddir'] = builddir
121 td['sigs'] = get_signatures(td['builddir'])
122 logger.info('')
123
124 for layer in layers:
125 if layer['type'] == LayerType.ERROR_NO_LAYER_CONF or \
126 layer['type'] == LayerType.ERROR_BSP_DISTRO:
127 continue
128
129 shutil.copyfile(bblayersconf + '.backup', bblayersconf)
130
131 add_layer(bblayersconf, layer)
132 result = test_layer_compatibility(td, layer)
133 results[layer['name']] = result
134
135 logger.info('')
136 logger.info('Summary of results:')
137 logger.info('')
138 for layer_name in results:
139 logger.info('%s ... %s' % (layer_name, 'PASS' if \
140 results[layer_name].wasSuccessful() else 'FAIL'))
141
142 cleanup_bblayers(None, None)
143
144 return 0
145
146if __name__ == '__main__':
147 try:
148 ret = main()
149 except Exception:
150 ret = 1
151 import traceback
152 traceback.print_exc()
153 sys.exit(ret)