| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 2 |  | 
|  | 3 | """ | 
|  | 4 | This script determines the given package's openbmc dependencies from its | 
|  | 5 | configure.ac file where it downloads, configures, builds, and installs each of | 
|  | 6 | these dependencies. Then the given package is configured, built, and installed | 
|  | 7 | prior to executing its unit tests. | 
|  | 8 | """ | 
|  | 9 |  | 
| Matthew Barth | d181037 | 2016-12-19 16:57:21 -0600 | [diff] [blame] | 10 | from git import Repo | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 11 | from urlparse import urljoin | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 12 | from subprocess import check_call, call | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 13 | import os | 
|  | 14 | import sys | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 15 | import argparse | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 16 | import re | 
|  | 17 |  | 
|  | 18 |  | 
|  | 19 | class DepTree(): | 
|  | 20 | """ | 
|  | 21 | Represents package dependency tree, where each node is a DepTree with a | 
|  | 22 | name and DepTree children. | 
|  | 23 | """ | 
|  | 24 |  | 
|  | 25 | def __init__(self, name): | 
|  | 26 | """ | 
|  | 27 | Create new DepTree. | 
|  | 28 |  | 
|  | 29 | Parameter descriptions: | 
|  | 30 | name               Name of new tree node. | 
|  | 31 | """ | 
|  | 32 | self.name = name | 
|  | 33 | self.children = list() | 
|  | 34 |  | 
|  | 35 | def AddChild(self, name): | 
|  | 36 | """ | 
|  | 37 | Add new child node to current node. | 
|  | 38 |  | 
|  | 39 | Parameter descriptions: | 
|  | 40 | name               Name of new child | 
|  | 41 | """ | 
|  | 42 | new_child = DepTree(name) | 
|  | 43 | self.children.append(new_child) | 
|  | 44 | return new_child | 
|  | 45 |  | 
|  | 46 | def AddChildNode(self, node): | 
|  | 47 | """ | 
|  | 48 | Add existing child node to current node. | 
|  | 49 |  | 
|  | 50 | Parameter descriptions: | 
|  | 51 | node               Tree node to add | 
|  | 52 | """ | 
|  | 53 | self.children.append(node) | 
|  | 54 |  | 
|  | 55 | def RemoveChild(self, name): | 
|  | 56 | """ | 
|  | 57 | Remove child node. | 
|  | 58 |  | 
|  | 59 | Parameter descriptions: | 
|  | 60 | name               Name of child to remove | 
|  | 61 | """ | 
|  | 62 | for child in self.children: | 
|  | 63 | if child.name == name: | 
|  | 64 | self.children.remove(child) | 
|  | 65 | return | 
|  | 66 |  | 
|  | 67 | def GetNode(self, name): | 
|  | 68 | """ | 
|  | 69 | Return node with matching name. Return None if not found. | 
|  | 70 |  | 
|  | 71 | Parameter descriptions: | 
|  | 72 | name               Name of node to return | 
|  | 73 | """ | 
|  | 74 | if self.name == name: | 
|  | 75 | return self | 
|  | 76 | for child in self.children: | 
|  | 77 | node = child.GetNode(name) | 
|  | 78 | if node: | 
|  | 79 | return node | 
|  | 80 | return None | 
|  | 81 |  | 
|  | 82 | def GetParentNode(self, name, parent_node=None): | 
|  | 83 | """ | 
|  | 84 | Return parent of node with matching name. Return none if not found. | 
|  | 85 |  | 
|  | 86 | Parameter descriptions: | 
|  | 87 | name               Name of node to get parent of | 
|  | 88 | parent_node        Parent of current node | 
|  | 89 | """ | 
|  | 90 | if self.name == name: | 
|  | 91 | return parent_node | 
|  | 92 | for child in self.children: | 
|  | 93 | found_node = child.GetParentNode(name, self) | 
|  | 94 | if found_node: | 
|  | 95 | return found_node | 
|  | 96 | return None | 
|  | 97 |  | 
|  | 98 | def GetPath(self, name, path=None): | 
|  | 99 | """ | 
|  | 100 | Return list of node names from head to matching name. | 
|  | 101 | Return None if not found. | 
|  | 102 |  | 
|  | 103 | Parameter descriptions: | 
|  | 104 | name               Name of node | 
|  | 105 | path               List of node names from head to current node | 
|  | 106 | """ | 
|  | 107 | if not path: | 
|  | 108 | path = [] | 
|  | 109 | if self.name == name: | 
|  | 110 | path.append(self.name) | 
|  | 111 | return path | 
|  | 112 | for child in self.children: | 
|  | 113 | match = child.GetPath(name, path + [self.name]) | 
|  | 114 | if match: | 
|  | 115 | return match | 
|  | 116 | return None | 
|  | 117 |  | 
|  | 118 | def GetPathRegex(self, name, regex_str, path=None): | 
|  | 119 | """ | 
|  | 120 | Return list of node paths that end in name, or match regex_str. | 
|  | 121 | Return empty list if not found. | 
|  | 122 |  | 
|  | 123 | Parameter descriptions: | 
|  | 124 | name               Name of node to search for | 
|  | 125 | regex_str          Regex string to match node names | 
|  | 126 | path               Path of node names from head to current node | 
|  | 127 | """ | 
|  | 128 | new_paths = [] | 
|  | 129 | if not path: | 
|  | 130 | path = [] | 
|  | 131 | match = re.match(regex_str, self.name) | 
|  | 132 | if (self.name == name) or (match): | 
|  | 133 | new_paths.append(path + [self.name]) | 
|  | 134 | for child in self.children: | 
|  | 135 | return_paths = None | 
|  | 136 | full_path = path + [self.name] | 
|  | 137 | return_paths = child.GetPathRegex(name, regex_str, full_path) | 
|  | 138 | for i in return_paths: | 
|  | 139 | new_paths.append(i) | 
|  | 140 | return new_paths | 
|  | 141 |  | 
|  | 142 | def MoveNode(self, from_name, to_name): | 
|  | 143 | """ | 
|  | 144 | Mode existing from_name node to become child of to_name node. | 
|  | 145 |  | 
|  | 146 | Parameter descriptions: | 
|  | 147 | from_name          Name of node to make a child of to_name | 
|  | 148 | to_name            Name of node to make parent of from_name | 
|  | 149 | """ | 
|  | 150 | parent_from_node = self.GetParentNode(from_name) | 
|  | 151 | from_node = self.GetNode(from_name) | 
|  | 152 | parent_from_node.RemoveChild(from_name) | 
|  | 153 | to_node = self.GetNode(to_name) | 
|  | 154 | to_node.AddChildNode(from_node) | 
|  | 155 |  | 
|  | 156 | def ReorderDeps(self, name, regex_str): | 
|  | 157 | """ | 
|  | 158 | Reorder dependency tree.  If tree contains nodes with names that | 
|  | 159 | match 'name' and 'regex_str', move 'regex_str' nodes that are | 
|  | 160 | to the right of 'name' node, so that they become children of the | 
|  | 161 | 'name' node. | 
|  | 162 |  | 
|  | 163 | Parameter descriptions: | 
|  | 164 | name               Name of node to look for | 
|  | 165 | regex_str          Regex string to match names to | 
|  | 166 | """ | 
|  | 167 | name_path = self.GetPath(name) | 
|  | 168 | if not name_path: | 
|  | 169 | return | 
|  | 170 | paths = self.GetPathRegex(name, regex_str) | 
|  | 171 | is_name_in_paths = False | 
|  | 172 | name_index = 0 | 
|  | 173 | for i in range(len(paths)): | 
|  | 174 | path = paths[i] | 
|  | 175 | if path[-1] == name: | 
|  | 176 | is_name_in_paths = True | 
|  | 177 | name_index = i | 
|  | 178 | break | 
|  | 179 | if not is_name_in_paths: | 
|  | 180 | return | 
|  | 181 | for i in range(name_index + 1, len(paths)): | 
|  | 182 | path = paths[i] | 
|  | 183 | if name in path: | 
|  | 184 | continue | 
|  | 185 | from_name = path[-1] | 
|  | 186 | self.MoveNode(from_name, name) | 
|  | 187 |  | 
|  | 188 | def GetInstallList(self): | 
|  | 189 | """ | 
|  | 190 | Return post-order list of node names. | 
|  | 191 |  | 
|  | 192 | Parameter descriptions: | 
|  | 193 | """ | 
|  | 194 | install_list = [] | 
|  | 195 | for child in self.children: | 
|  | 196 | child_install_list = child.GetInstallList() | 
|  | 197 | install_list.extend(child_install_list) | 
|  | 198 | install_list.append(self.name) | 
|  | 199 | return install_list | 
|  | 200 |  | 
|  | 201 | def PrintTree(self, level=0): | 
|  | 202 | """ | 
|  | 203 | Print pre-order node names with indentation denoting node depth level. | 
|  | 204 |  | 
|  | 205 | Parameter descriptions: | 
|  | 206 | level              Current depth level | 
|  | 207 | """ | 
|  | 208 | INDENT_PER_LEVEL = 4 | 
|  | 209 | print ' ' * (level * INDENT_PER_LEVEL) + self.name | 
|  | 210 | for child in self.children: | 
|  | 211 | child.PrintTree(level + 1) | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 212 |  | 
|  | 213 |  | 
|  | 214 | def check_call_cmd(dir, *cmd): | 
|  | 215 | """ | 
|  | 216 | Verbose prints the directory location the given command is called from and | 
|  | 217 | the command, then executes the command using check_call. | 
|  | 218 |  | 
|  | 219 | Parameter descriptions: | 
|  | 220 | dir                 Directory location command is to be called from | 
|  | 221 | cmd                 List of parameters constructing the complete command | 
|  | 222 | """ | 
|  | 223 | printline(dir, ">", " ".join(cmd)) | 
|  | 224 | check_call(cmd) | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 225 |  | 
|  | 226 |  | 
|  | 227 | def clone_pkg(pkg): | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 228 | """ | 
|  | 229 | Clone the given openbmc package's git repository from gerrit into | 
|  | 230 | the WORKSPACE location | 
|  | 231 |  | 
|  | 232 | Parameter descriptions: | 
|  | 233 | pkg                 Name of the package to clone | 
|  | 234 | """ | 
| Andrew Jeffery | 7be94ca | 2018-03-08 13:15:33 +1030 | [diff] [blame] | 235 | pkg_dir = os.path.join(WORKSPACE, pkg) | 
|  | 236 | if os.path.exists(os.path.join(pkg_dir, '.git')): | 
|  | 237 | return pkg_dir | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 238 | pkg_repo = urljoin('https://gerrit.openbmc-project.xyz/openbmc/', pkg) | 
| Andrew Jeffery | 7be94ca | 2018-03-08 13:15:33 +1030 | [diff] [blame] | 239 | os.mkdir(pkg_dir) | 
|  | 240 | printline(pkg_dir, "> git clone", pkg_repo, "./") | 
|  | 241 | return Repo.clone_from(pkg_repo, pkg_dir).working_dir | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 242 |  | 
|  | 243 |  | 
|  | 244 | def get_deps(configure_ac): | 
|  | 245 | """ | 
|  | 246 | Parse the given 'configure.ac' file for package dependencies and return | 
|  | 247 | a list of the dependencies found. | 
|  | 248 |  | 
|  | 249 | Parameter descriptions: | 
|  | 250 | configure_ac        Opened 'configure.ac' file object | 
|  | 251 | """ | 
|  | 252 | line = "" | 
| Brad Bishop | ebb4911 | 2017-02-13 11:07:26 -0500 | [diff] [blame] | 253 | dep_pkgs = set() | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 254 | for cfg_line in configure_ac: | 
|  | 255 | # Remove whitespace & newline | 
|  | 256 | cfg_line = cfg_line.rstrip() | 
|  | 257 | # Check for line breaks | 
|  | 258 | if cfg_line.endswith('\\'): | 
|  | 259 | line += str(cfg_line[:-1]) | 
|  | 260 | continue | 
|  | 261 | line = line+cfg_line | 
|  | 262 |  | 
|  | 263 | # Find any defined dependency | 
| Brad Bishop | ebb4911 | 2017-02-13 11:07:26 -0500 | [diff] [blame] | 264 | line_has = lambda x: x if x in line else None | 
|  | 265 | macros = set(filter(line_has, DEPENDENCIES.iterkeys())) | 
|  | 266 | if len(macros) == 1: | 
|  | 267 | macro = ''.join(macros) | 
|  | 268 | deps = filter(line_has, DEPENDENCIES[macro].iterkeys()) | 
|  | 269 | dep_pkgs.update(map(lambda x: DEPENDENCIES[macro][x], deps)) | 
|  | 270 |  | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 271 | line = "" | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 272 | deps = list(dep_pkgs) | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 273 |  | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 274 | return deps | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 275 |  | 
|  | 276 |  | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 277 | def install_deps(dep_list): | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 278 | """ | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 279 | Install each package in the ordered dep_list. | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 280 |  | 
|  | 281 | Parameter descriptions: | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 282 | dep_list            Ordered list of dependencies | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 283 | """ | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 284 | for pkg in dep_list: | 
|  | 285 | pkgdir = os.path.join(WORKSPACE, pkg) | 
|  | 286 | # Build & install this package | 
| Matthew Barth | 1d1c673 | 2017-03-24 10:00:28 -0500 | [diff] [blame] | 287 | conf_flags = [] | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 288 | os.chdir(pkgdir) | 
|  | 289 | # Add any necessary configure flags for package | 
|  | 290 | if CONFIGURE_FLAGS.get(pkg) is not None: | 
| Matthew Barth | 1d1c673 | 2017-03-24 10:00:28 -0500 | [diff] [blame] | 291 | conf_flags.extend(CONFIGURE_FLAGS.get(pkg)) | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 292 | check_call_cmd(pkgdir, './bootstrap.sh') | 
| Matthew Barth | 1d1c673 | 2017-03-24 10:00:28 -0500 | [diff] [blame] | 293 | check_call_cmd(pkgdir, './configure', *conf_flags) | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 294 | check_call_cmd(pkgdir, 'make') | 
|  | 295 | check_call_cmd(pkgdir, 'make', 'install') | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 296 |  | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 297 |  | 
|  | 298 | def build_dep_tree(pkg, pkgdir, dep_added, head, dep_tree=None): | 
|  | 299 | """ | 
|  | 300 | For each package(pkg), starting with the package to be unit tested, | 
|  | 301 | parse its 'configure.ac' file from within the package's directory(pkgdir) | 
|  | 302 | for each package dependency defined recursively doing the same thing | 
|  | 303 | on each package found as a dependency. | 
|  | 304 |  | 
|  | 305 | Parameter descriptions: | 
|  | 306 | pkg                 Name of the package | 
|  | 307 | pkgdir              Directory where package source is located | 
|  | 308 | dep_added           Current list of dependencies and added status | 
|  | 309 | head                Head node of the dependency tree | 
|  | 310 | dep_tree            Current dependency tree node | 
|  | 311 | """ | 
|  | 312 | if not dep_tree: | 
|  | 313 | dep_tree = head | 
|  | 314 | os.chdir(pkgdir) | 
|  | 315 | # Open package's configure.ac | 
| Andrew Jeffery | 2cb0c7a | 2018-03-08 13:19:08 +1030 | [diff] [blame^] | 316 | with open("/root/.depcache", "r") as depcache: | 
|  | 317 | cached = depcache.readline() | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 318 | with open("configure.ac", "rt") as configure_ac: | 
|  | 319 | # Retrieve dependency list from package's configure.ac | 
|  | 320 | configure_ac_deps = get_deps(configure_ac) | 
|  | 321 | for dep_pkg in configure_ac_deps: | 
| Andrew Jeffery | 2cb0c7a | 2018-03-08 13:19:08 +1030 | [diff] [blame^] | 322 | if dep_pkg in cached: | 
|  | 323 | continue | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 324 | # Dependency package not already known | 
|  | 325 | if dep_added.get(dep_pkg) is None: | 
|  | 326 | # Dependency package not added | 
|  | 327 | new_child = dep_tree.AddChild(dep_pkg) | 
|  | 328 | dep_added[dep_pkg] = False | 
| Andrew Jeffery | 7be94ca | 2018-03-08 13:15:33 +1030 | [diff] [blame] | 329 | dep_pkgdir = clone_pkg(dep_pkg) | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 330 | # Determine this dependency package's | 
|  | 331 | # dependencies and add them before | 
|  | 332 | # returning to add this package | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 333 | dep_added = build_dep_tree(dep_pkg, | 
| Andrew Jeffery | 7be94ca | 2018-03-08 13:15:33 +1030 | [diff] [blame] | 334 | dep_pkgdir, | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 335 | dep_added, | 
|  | 336 | head, | 
|  | 337 | new_child) | 
|  | 338 | else: | 
|  | 339 | # Dependency package known and added | 
|  | 340 | if dep_added[dep_pkg]: | 
|  | 341 | continue | 
|  | 342 | else: | 
|  | 343 | # Cyclic dependency failure | 
|  | 344 | raise Exception("Cyclic dependencies found in "+pkg) | 
|  | 345 |  | 
|  | 346 | if not dep_added[pkg]: | 
|  | 347 | dep_added[pkg] = True | 
|  | 348 |  | 
|  | 349 | return dep_added | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 350 |  | 
|  | 351 |  | 
|  | 352 | if __name__ == '__main__': | 
|  | 353 | # CONFIGURE_FLAGS = [GIT REPO]:[CONFIGURE FLAGS] | 
|  | 354 | CONFIGURE_FLAGS = { | 
| Adriana Kobylak | 43c31e8 | 2017-02-13 09:28:35 -0600 | [diff] [blame] | 355 | 'phosphor-objmgr': ['--enable-unpatched-systemd'], | 
| Matthew Barth | 1d1c673 | 2017-03-24 10:00:28 -0500 | [diff] [blame] | 356 | 'sdbusplus': ['--enable-transaction'], | 
|  | 357 | 'phosphor-logging': | 
|  | 358 | ['--enable-metadata-processing', | 
| Deepak Kodihalli | 3a4e1b4 | 2017-06-08 09:52:35 -0500 | [diff] [blame] | 359 | 'YAML_DIR=/usr/local/share/phosphor-dbus-yaml/yaml'] | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 360 | } | 
|  | 361 |  | 
|  | 362 | # DEPENDENCIES = [MACRO]:[library/header]:[GIT REPO] | 
|  | 363 | DEPENDENCIES = { | 
|  | 364 | 'AC_CHECK_LIB': {'mapper': 'phosphor-objmgr'}, | 
| Matthew Barth | 710f3f0 | 2017-01-18 15:20:19 -0600 | [diff] [blame] | 365 | 'AC_CHECK_HEADER': { | 
|  | 366 | 'host-ipmid': 'phosphor-host-ipmid', | 
|  | 367 | 'sdbusplus': 'sdbusplus', | 
| Saqib Khan | 6614505 | 2017-02-14 12:02:07 -0600 | [diff] [blame] | 368 | 'phosphor-logging/log.hpp': 'phosphor-logging', | 
| Patrick Williams | eab8a37 | 2017-01-30 11:21:32 -0600 | [diff] [blame] | 369 | }, | 
| Brad Bishop | ebb4911 | 2017-02-13 11:07:26 -0500 | [diff] [blame] | 370 | 'AC_PATH_PROG': {'sdbus++': 'sdbusplus'}, | 
| Patrick Williams | eab8a37 | 2017-01-30 11:21:32 -0600 | [diff] [blame] | 371 | 'PKG_CHECK_MODULES': { | 
| Matthew Barth | 19e261e | 2017-02-01 12:55:22 -0600 | [diff] [blame] | 372 | 'phosphor-dbus-interfaces': 'phosphor-dbus-interfaces', | 
| Patrick Williams | f128b40 | 2017-03-29 06:45:59 -0500 | [diff] [blame] | 373 | 'openpower-dbus-interfaces': 'openpower-dbus-interfaces', | 
| Brad Bishop | ebb4911 | 2017-02-13 11:07:26 -0500 | [diff] [blame] | 374 | 'sdbusplus': 'sdbusplus', | 
|  | 375 | 'phosphor-logging': 'phosphor-logging', | 
|  | 376 | }, | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 377 | } | 
|  | 378 |  | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 379 | # DEPENDENCIES_REGEX = [GIT REPO]:[REGEX STRING] | 
|  | 380 | DEPENDENCIES_REGEX = { | 
|  | 381 | 'phosphor-logging': '\S+-dbus-interfaces$' | 
|  | 382 | } | 
|  | 383 |  | 
| Matthew Barth | 33df879 | 2016-12-19 14:30:17 -0600 | [diff] [blame] | 384 | # Set command line arguments | 
|  | 385 | parser = argparse.ArgumentParser() | 
|  | 386 | parser.add_argument("-w", "--workspace", dest="WORKSPACE", required=True, | 
|  | 387 | help="Workspace directory location(i.e. /home)") | 
|  | 388 | parser.add_argument("-p", "--package", dest="PACKAGE", required=True, | 
|  | 389 | help="OpenBMC package to be unit tested") | 
|  | 390 | parser.add_argument("-v", "--verbose", action="store_true", | 
|  | 391 | help="Print additional package status messages") | 
|  | 392 | args = parser.parse_args(sys.argv[1:]) | 
|  | 393 | WORKSPACE = args.WORKSPACE | 
|  | 394 | UNIT_TEST_PKG = args.PACKAGE | 
|  | 395 | if args.verbose: | 
|  | 396 | def printline(*line): | 
|  | 397 | for arg in line: | 
|  | 398 | print arg, | 
|  | 399 | print | 
|  | 400 | else: | 
|  | 401 | printline = lambda *l: None | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 402 |  | 
| Adriana Kobylak | bcee22b | 2018-01-10 16:58:27 -0600 | [diff] [blame] | 403 | # First validate code formattting if repo has style formatting files. | 
|  | 404 | # The format-code.sh checks for these files. | 
| Andrew Geissler | a28286d | 2018-01-10 11:00:00 -0800 | [diff] [blame] | 405 | CODE_SCAN_DIR = WORKSPACE + "/" + UNIT_TEST_PKG | 
| Adriana Kobylak | bcee22b | 2018-01-10 16:58:27 -0600 | [diff] [blame] | 406 | check_call_cmd(WORKSPACE, "./format-code.sh", CODE_SCAN_DIR) | 
| Andrew Geissler | a28286d | 2018-01-10 11:00:00 -0800 | [diff] [blame] | 407 |  | 
| Andrew Geissler | 71a7cc1 | 2018-01-31 14:18:37 -0800 | [diff] [blame] | 408 | # The rest of this script is CI testing, which currently only supports | 
|  | 409 | # Automake based repos. Check if this repo is Automake, if not exit | 
|  | 410 | if not os.path.isfile(CODE_SCAN_DIR + "/configure.ac"): | 
|  | 411 | print "Not a supported repo for CI Tests, exit" | 
|  | 412 | quit() | 
|  | 413 |  | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 414 | prev_umask = os.umask(000) | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 415 | # Determine dependencies and add them | 
|  | 416 | dep_added = dict() | 
|  | 417 | dep_added[UNIT_TEST_PKG] = False | 
|  | 418 | # Create dependency tree | 
|  | 419 | dep_tree = DepTree(UNIT_TEST_PKG) | 
|  | 420 | build_dep_tree(UNIT_TEST_PKG, | 
|  | 421 | os.path.join(WORKSPACE, UNIT_TEST_PKG), | 
|  | 422 | dep_added, | 
|  | 423 | dep_tree) | 
|  | 424 |  | 
|  | 425 | # Reorder Dependency Tree | 
|  | 426 | for pkg_name, regex_str in DEPENDENCIES_REGEX.iteritems(): | 
|  | 427 | dep_tree.ReorderDeps(pkg_name, regex_str) | 
|  | 428 | if args.verbose: | 
|  | 429 | dep_tree.PrintTree() | 
|  | 430 | install_list = dep_tree.GetInstallList() | 
| Gunnar Mills | 5f81180 | 2017-10-25 16:10:27 -0500 | [diff] [blame] | 431 | # install reordered dependencies | 
| Leonel Gonzalez | a62a1a1 | 2017-03-24 11:03:47 -0500 | [diff] [blame] | 432 | install_deps(install_list) | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 433 | os.chdir(os.path.join(WORKSPACE, UNIT_TEST_PKG)) | 
| Matthew Barth | 948b7cc | 2017-02-21 09:13:54 -0600 | [diff] [blame] | 434 | # Refresh dynamic linker run time bindings for dependencies | 
|  | 435 | check_call_cmd(os.path.join(WORKSPACE, UNIT_TEST_PKG), 'ldconfig') | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 436 | # Run package unit tests | 
| Matthew Barth | 4ecbc9c | 2017-02-17 10:34:46 -0600 | [diff] [blame] | 437 | if args.verbose: | 
|  | 438 | check_call_cmd(os.path.join(WORKSPACE, UNIT_TEST_PKG), 'make', 'check', | 
|  | 439 | 'VERBOSE=1') | 
|  | 440 | else: | 
|  | 441 | check_call_cmd(os.path.join(WORKSPACE, UNIT_TEST_PKG), 'make', 'check') | 
| Matthew Barth | ccb7f85 | 2016-11-23 17:43:02 -0600 | [diff] [blame] | 442 | os.umask(prev_umask) |