summaryrefslogtreecommitdiffstats
path: root/scripts/yocto-compat-layer.py
diff options
context:
space:
mode:
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)