def _parse_launch(tags, launch_file, file_deps, verbose, context): dir_path = os.path.dirname(os.path.abspath(launch_file)) launch_file_pkg = rospkg.get_package_name(dir_path) # process group, include, node, and test tags from launch file for tag in [t for t in tags if t.nodeType == DomNode.ELEMENT_NODE]: if tag.tagName == 'group': #descend group tags as they can contain node tags _parse_launch(tag.childNodes, launch_file, file_deps, verbose, context) elif tag.tagName == 'arg': v = _parse_arg(tag, context) if v: (name, val) = v context['arg'][name] = val elif tag.tagName == 'include': try: sub_launch_file = resolve_args(tag.attributes['file'].value, context) except KeyError as e: raise RoslaunchDepsException("Cannot load roslaunch <%s> tag: missing required attribute %s.\nXML is %s"%(tag.tagName, str(e), tag.toxml())) if verbose: print("processing included launch %s"%sub_launch_file) # determine package dependency for included file sub_pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(sub_launch_file))) if sub_pkg is None: print("ERROR: cannot determine package for [%s]"%sub_launch_file, file=sys.stderr) if sub_launch_file not in file_deps[launch_file].includes: file_deps[launch_file].includes.append(sub_launch_file) if launch_file_pkg != sub_pkg: file_deps[launch_file].pkgs.append(sub_pkg) # recurse file_deps[sub_launch_file] = RoslaunchDeps() try: dom = parse(sub_launch_file).getElementsByTagName('launch') if not len(dom): print("ERROR: %s is not a valid roslaunch file"%sub_launch_file, file=sys.stderr) else: launch_tag = dom[0] sub_context = _parse_subcontext(tag.childNodes, context) _parse_launch(launch_tag.childNodes, sub_launch_file, file_deps, verbose, sub_context) except IOError as e: raise RoslaunchDepsException("Cannot load roslaunch include '%s' in '%s'"%(sub_launch_file, launch_file)) elif tag.tagName in ['node', 'test']: try: pkg, type = [resolve_args(tag.attributes[a].value, context) for a in ['pkg', 'type']] except KeyError as e: raise RoslaunchDepsException("Cannot load roslaunch <%s> tag: missing required attribute %s.\nXML is %s"%(tag.tagName, str(e), tag.toxml())) if (pkg, type) not in file_deps[launch_file].nodes: file_deps[launch_file].nodes.append((pkg, type)) # we actually want to include the package itself if that's referenced #if launch_file_pkg != pkg: if pkg not in file_deps[launch_file].pkgs: file_deps[launch_file].pkgs.append(pkg)
def test_get_package_name(): from rospkg import get_package_name # test dir is a subdirectory of this package test_dir = get_package_test_path() assert 'rospkg' == get_package_name(test_dir), get_package_name(test_dir) test_dir_foo = os.path.join(test_dir, 'p1', 'foo') assert 'foo' == get_package_name(test_dir_foo) # test with path outside of our hierarchy assert None == get_package_name(tempfile.tempdir)
def test_get_package_name(): from rospkg import get_package_name # test dir is a subdirectory of this package test_dir = get_package_test_path() assert "rospkg" == get_package_name(test_dir), get_package_name(test_dir) test_dir_foo = os.path.join(test_dir, "p1", "foo") assert "foo" == get_package_name(test_dir_foo) # test with path outside of our hierarchy assert None == get_package_name(tempfile.tempdir)
def test_get_package_name(): from rospkg import __version__ from rospkg import get_package_name # test dir is a subdirectory of this package test_dir = get_package_test_path() assert get_package_name(test_dir) in ['rospkg', 'rospkg-%s' % __version__], get_package_name(test_dir) test_dir_foo = os.path.join(test_dir, 'p1', 'foo') assert 'foo' == get_package_name(test_dir_foo) # test with path outside of our hierarchy assert None == get_package_name(tempfile.tempdir)
def test_get_package_name(): from rospkg import __version__ from rospkg import get_package_name test_dir = get_package_test_path() test_dir_foo = os.path.join(test_dir, 'p1', 'foo') assert 'foo' == get_package_name(test_dir_foo) # baz dir is a subdirectory of foo package test_dir_foo_baz = os.path.join(test_dir_foo, 'baz') assert 'foo' == get_package_name(test_dir_foo_baz) # test with path outside of our hierarchy assert get_package_name(tempfile.tempdir) is None
def FlagsForCompilationDatabase(root, filename): try: try: import rospkg except ImportError: return '' pkg_name = rospkg.get_package_name(filename) if pkg_name: compilation_db_dir = (os.path.expandvars('$ROS_WORKSPACE') + os.path.sep + 'build' + os.path.sep + pkg_name) else: # Last argument of next function is the name of the build folder for # out of source projects compilation_db_path = FindNearest(root, 'compile_commands.json', BUILD_DIRECTORY) compilation_db_dir = os.path.dirname(compilation_db_path) logging.info("Set compilation database directory to " + compilation_db_dir) compilation_db = ycm_core.CompilationDatabase(compilation_db_dir) if not compilation_db: logging.info("Compilation database file found but unable to load") return None compilation_info = GetCompilationInfoForFile(compilation_db, filename) if not compilation_info: logging.info("No compilation info for " + filename + " in compilation database") return None return MakeRelativePathsInFlagsAbsolute( compilation_info.compiler_flags_, compilation_info.compiler_working_dir_) except: return None
def genmain(argv, subdir): rospack = rospkg.RosPack() try: gen_initpy = '--initpy' in argv no_gen_initpy = '--noinitpy' in argv if gen_initpy: # #1827 # new __init__py does not take explicit file args. just # convert to unique package names and compute path. files = [f for f in argv[1:] if not f.startswith('--')] packages = list(set([rospkg.get_package_name(f) for f in files])) retcodes = [generate_initpy(rospack, p, subdir) for p in packages] retcodes = [c for c in retcodes if c not in (0, None)] if retcodes: retcode = retcodes[0] else: retcode = 0 else: package, msg_file = get_package_and_file(argv) retcode = generate_messages(rospack, package, msg_file, subdir) except genmsg.InvalidMsgSpec as e: sys.stderr.write("ERROR: %s\n"%(str(e))) retcode = 1 except genmsg.MsgGenerationException as e: sys.stderr.write("ERROR: %s\n"%(str(e))) retcode = 2 except Exception as e: traceback.print_exc() sys.stderr.write("ERROR: %s\n"%(str(e))) retcode = 3 sys.exit(retcode or 0)
def GetWorkspacePath(filename): try: import rospkg except ImportError: return '' pkg_name = rospkg.get_package_name(filename) if not pkg_name: return '' # get the content of $ROS_WORKSPACE variable # and create an array out of it paths = os.path.expandvars('$ROS_WORKSPACE') workspaces = paths.split() # iterate over all workspaces for single_workspace in workspaces: # get the full path to the workspace workspace_path = os.path.expanduser(single_workspace) # get all ros packages built in workspace's build directory paths = glob(workspace_path + "/build/*") # iterate over all the packages built in the workspace for package_path in paths: # test whether the package, to which "filename" belongs to, is in the workspace if package_path.endswith(pkg_name): # if it is, return path to its workspace return workspace_path return 0
def GetCompilationInfoForHeaderRos(headerfile, database): """Return the compile flags for the corresponding src file in ROS Return the compile flags for the source file corresponding to the header file in the ROS where the header file is. """ try: import rospkg except ImportError: return None pkg_name = rospkg.get_package_name(headerfile) if not pkg_name: return None try: pkg_path = rospkg.RosPack().get_path(pkg_name) except rospkg.ResourceNotFound: return None filename_no_ext = os.path.splitext(headerfile)[0] hdr_basename_no_ext = os.path.basename(filename_no_ext) for path, dirs, files in os.walk(pkg_path): for src_filename in files: src_basename_no_ext = os.path.splitext(src_filename)[0] if hdr_basename_no_ext != src_basename_no_ext: continue for extension in SOURCE_EXTENSIONS: if src_filename.endswith(extension): compilation_info = database.GetCompilationInfoForFile( path + os.path.sep + src_filename) if compilation_info.compiler_flags_: return compilation_info return None
def roslaunch_deps(files, verbose=False): """ @param packages: list of packages to check @type packages: [str] @param files [str]: list of roslaunch files to check. Must be in same package. @type files: [str] @return: base_pkg, file_deps, missing. base_pkg is the package of all files file_deps is a { filename : RoslaunchDeps } dictionary of roslaunch dependency information to update, indexed by roslaunch file name. missing is a { package : [packages] } dictionary of missing manifest dependencies, indexed by package. @rtype: str, dict, dict """ file_deps = {} missing = {} base_pkg = None for launch_file in files: if not os.path.exists(launch_file): raise RoslaunchDepsException("roslaunch file [%s] does not exist"%launch_file) pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(launch_file))) if base_pkg and pkg != base_pkg: raise RoslaunchDepsException("roslaunch files must be in the same package: %s vs. %s"%(base_pkg, pkg)) base_pkg = pkg rl_file_deps(file_deps, launch_file, verbose) calculate_missing(base_pkg, missing, file_deps) return base_pkg, file_deps, missing
def GetCompilationDatabaseFolder(filename): """Return the directory potentially containing compilation_commands.json Return the absolute path to the folder (NOT the file!) containing the compile_commands.json file to use that instead of 'flags'. See here for more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html. The compilation_commands.json for the given file is returned by getting the package the file belongs to. """ ros_workspace = os.path.expandvars('$ROS_WORKSPACE') path = '' if ros_workspace: if os.path.exists(os.path.join(ros_workspace,'build','compile_commands.json')): path = os.path.join(ros_workspace,'build') else: # search path looking for compile_commands.json: try: import rospkg except ImportError: return path pkg_name = rospkg.get_package_name(filename) if pkg_name: if os.path.exists(os.path.join(ros_workspace, "build", pkg_name, "compile_commands.json")): path = os.path.join(ros_workspace, "build", pkg_name) return path
def update_file_format(self, frame): if frame.package == "" and frame.path != "": try: import rospkg import os from python_qt_binding import QtWidgets rospackage = rospkg.get_package_name(frame.path) if rospackage is not None: rel_path = os.path.relpath( frame.path, rospkg.RosPack().get_path(rospackage)) reply = QtWidgets.QMessageBox.question( None, "Convert absolute path to rospack+relative path?", "The absolute path to your selected mesh can be converted to rospack+relative path." + "This gives you more reliabilaty to reuse your saved configuration" + "if your meshes are stored in rospackages\n\n" + "Do you want to convert your configuration?\n" + "Convert:\n'{}'\nto:\n'{}' and\n '{}'\n".format( frame.path, rospackage, rel_path), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) if reply == QtWidgets.QMessageBox.Yes: print "Saving: package:", rospackage, "+ relative path:", rel_path frame.package = rospackage frame.path = rel_path return except: # Do nothing if conversion fails pass else: # Do nothing if conversion not needed pass
def genmain(argv, subdir): rospack = rospkg.RosPack() try: gen_initpy = '--initpy' in argv no_gen_initpy = '--noinitpy' in argv if gen_initpy: # #1827 # new __init__py does not take explicit file args. just # convert to unique package names and compute path. files = [f for f in argv[1:] if not f.startswith('--')] packages = list(set([rospkg.get_package_name(f) for f in files])) retcodes = [generate_initpy(rospack, p, subdir) for p in packages] retcodes = [c for c in retcodes if c not in (0, None)] if retcodes: retcode = retcodes[0] else: retcode = 0 else: package, msg_file = get_package_and_file(argv) retcode = generate_messages(rospack, package, msg_file, subdir) except genmsg.InvalidMsgSpec as e: sys.stderr.write("ERROR: %s\n" % (str(e))) retcode = 1 except genmsg.MsgGenerationException as e: sys.stderr.write("ERROR: %s\n" % (str(e))) retcode = 2 except Exception as e: traceback.print_exc() sys.stderr.write("ERROR: %s\n" % (str(e))) retcode = 3 sys.exit(retcode or 0)
def calculate_missing(base_pkg, missing, file_deps): """ Calculate missing package dependencies in the manifest. This is mainly used as a subroutine of roslaunch_deps(). @param base_pkg: name of package where initial walk begins (unused). @type base_pkg: str @param missing: dictionary mapping package names to set of missing package dependencies. @type missing: { str: set(str) } @param file_deps: dictionary mapping launch file names to RoslaunchDeps of each file @type file_deps: { str: RoslaunchDeps} @return: missing (see parameter) @rtype: { str: set(str) } """ rospack = rospkg.RosPack() for launch_file in file_deps.iterkeys(): pkg = rospkg.get_package_name( os.path.dirname(os.path.abspath(launch_file))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]" % pkg, file=sys.stderr) continue m = rospack.get_manifest(pkg) d_pkgs = set([d.name for d in m.depends]) # make sure we don't count ourselves as a dep d_pkgs.add(pkg) diff = list(set(file_deps[launch_file].pkgs) - d_pkgs) if not pkg in missing: missing[pkg] = set() missing[pkg].update(diff) return missing
def roslaunch_deps(files, verbose=False, use_test_depends=False): """ @param packages: list of packages to check @type packages: [str] @param files [str]: list of roslaunch files to check. Must be in same package. @type files: [str] @param use_test_depends [bool]: use test_depends as installed package @type use_test_depends: [bool] @return: base_pkg, file_deps, missing. base_pkg is the package of all files file_deps is a { filename : RoslaunchDeps } dictionary of roslaunch dependency information to update, indexed by roslaunch file name. missing is a { package : [packages] } dictionary of missing manifest dependencies, indexed by package. @rtype: str, dict, dict """ file_deps = {} missing = {} base_pkg = None for launch_file in files: if not os.path.exists(launch_file): raise RoslaunchDepsException("roslaunch file [%s] does not exist"%launch_file) pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(launch_file))) if base_pkg and pkg != base_pkg: raise RoslaunchDepsException("roslaunch files must be in the same package: %s vs. %s"%(base_pkg, pkg)) base_pkg = pkg rl_file_deps(file_deps, launch_file, verbose) calculate_missing(base_pkg, missing, file_deps, use_test_depends=use_test_depends) return base_pkg, file_deps, missing
def GetCompilationDatabaseFolder(filename): """Return the directory potentially containing compilation_commands.json Return the absolute path to the folder (NOT the file!) containing the compile_commands.json file to use that instead of 'flags'. See here for more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html. The compilation_commands.json for the given file is returned by getting the package the file belongs to. """ try: import rospkg except ImportError: return '' pkg_name = rospkg.get_package_name(filename) if not pkg_name: return '' workspace_path = GetWorkspacePath(filename) if not workspace_path: return '' dir = (workspace_path + os.path.sep + 'build' + os.path.sep + pkg_name) return dir
def getPackageName(self): """Get the name of the package that contains this launch file.""" packageName = rospkg.get_package_name(self.__filename) if not packageName: raise Exception("Failed to get package name for: %s" % self.__filename) return packageName
def file_path_changed(self): file_path = str(self.file_text.text()) file_path = file_path.strip() if self.urdf_is_valid(file_path): self.urdf_path = file_path self.load_button.setEnabled(True) self.file_text.setText(self.urdf_path) self.file_format = "urdf" package_name = rospkg.get_package_name(file_path) if package_name == None: self.description_path = file_path return try: start = file_path.index(package_name) + len(package_name) filename = os.path.basename(file_path) end = file_path.index(filename) file_sub_path = file_path[start:end] self.description_path = "$(find %s)%s%s" % ( package_name, file_sub_path, filename) except: pass elif self.config_is_valid(file_path): self.config_path = file_path self.load_button.setEnabled(True) self.file_text.setText(self.urdf_path) self.file_format = "json" else: self.load_button.setEnabled(False)
def GetWorkspacePath(filename): pkg_name = rospkg.get_package_name(filename) if not pkg_name: return '' paths = [] if not ENV_WORKSPACES in os.environ: raise ValueError( "The {} environmental variable is not set!".format(ENV_WORKSPACES)) else: paths = os.environ[ENV_WORKSPACES] workspaces = paths.split() # iterate over all workspaces for single_workspace in workspaces: # get the full path to the workspace workspace_path = os.path.expanduser(single_workspace) # get all ros packages built in workspace's build directory paths = glob(workspace_path + "/build/*") # iterate over all the packages built in the workspace for package_path in paths: # test whether the package, to which "filename" belongs to, is in the workspace if package_path.endswith(pkg_name): # if it is, return path to its workspace return workspace_path return 0
def calculate_missing(base_pkg, missing, file_deps): """ Calculate missing package dependencies in the manifest. This is mainly used as a subroutine of roslaunch_deps(). @param base_pkg: name of package where initial walk begins (unused). @type base_pkg: str @param missing: dictionary mapping package names to set of missing package dependencies. @type missing: { str: set(str) } @param file_deps: dictionary mapping launch file names to RoslaunchDeps of each file @type file_deps: { str: RoslaunchDeps} @return: missing (see parameter) @rtype: { str: set(str) } """ rospack = rospkg.RosPack() for launch_file in file_deps.iterkeys(): pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(launch_file))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]"%pkg, file=sys.stderr) continue m = rospack.get_manifest(pkg) d_pkgs = set([d.name for d in m.depends]) # make sure we don't count ourselves as a dep d_pkgs.add(pkg) diff = list(set(file_deps[launch_file].pkgs) - d_pkgs) if not pkg in missing: missing[pkg] = set() missing[pkg].update(diff) return missing
def fill_component(self, component_name, file_path, is_server=True): """ Given a provided file path, extract the proper information to fill the component attribute @param component_name: Name of the component @param file_path: Path to the file corresponding to either a server or action @param is_server: State whether the file corresponds to a server. Default is True @return: True if the provided file is valid, False otherwise """ # Get the package name ros_pkg_name = rospkg.get_package_name(file_path) # If the file is not part of a ROS package if not ros_pkg_name: error_message("Error message", "The provided file must be part of a ROS package", parent=self) return False # If the file has been deleted elif not os.path.exists(file_path): error_message("Error message", "The file {} cannot be found".format(file_path), parent=self) return False # Fill the component attribute if is_server: self.components[component_name]["server_package"] = ros_pkg_name else: self.components[component_name]["action_package"] = ros_pkg_name return True
def get_file_dependencies(f, stdout=sys.stdout, stderr=sys.stderr, rospack=None): """ Compute dependencies of the specified message/service file @param f: message or service file to get dependencies for @type f: str @param stdout pipe: stdout pipe @type stdout: file @param stderr pipe: stderr pipe @type stderr: file @return: 'files': list of files that \a file depends on, 'deps': list of dependencies by type, 'spec': Msgs/Srvs instance. @rtype: dict """ package = rospkg.get_package_name(f) spec = None if f.endswith(roslib.msgs.EXT): _, spec = roslib.msgs.load_from_file(f) elif f.endswith(roslib.srvs.EXT): _, spec = roslib.srvs.load_from_file(f) else: raise Exception("[%s] does not appear to be a message or service" % spec) return get_dependencies(spec, package, stdout, stderr, rospack=rospack)
def _parse_arguments(): ''' @raise IOError : if no package name is given and the rocon launcher cannot be found on the filesystem. ''' parser = argparse.ArgumentParser(description=help_string(), formatter_class=RawTextHelpFormatter) parser.add_argument( 'package', nargs='?', default=None, help='name of the package in which to find the test configuration') parser.add_argument('test', nargs=1, help='name of the test configuration (xml) file') # not yet supported # parser.add_argument('-l', '--launch', action='store_true', help='launch each component with rocon_launch [false]') parser.add_argument( '-p', '--pause', action='store_true', help='pause before tearing down so you can introspect easily [false]') parser.add_argument( '-n', '--no-screen', action='store_true', help='do run each roslaunch with the --screen option [true]') parser.add_argument( '-t', '--text-mode', action='store_true', help='log the rostest output to screen rather than log file.') parser.add_argument("--results-filename", action='store', type=str, default=None, help="results_filename") parser.add_argument( '--results-base-dir', action='store', default='', help= "The base directory of the test results. The test result file is created in a subfolder name PKG_DIR." ) args = parser.parse_args() # Stop it from being a list (happens when nargs is an integer) args.test = args.test[0] launch_arguments = "" if not args.no_screen: launch_arguments = "--screen" if not args.package: if not os.path.isfile(args.test): raise IOError("Test launcher file does not exist [%s]." % args.test) else: args.package = rospkg.get_package_name(args.test) return (args.package, args.test, launch_arguments, args.pause, args.text_mode, args.results_filename, args.results_base_dir)
def check_input_validity(self): """ Check if the current text corresponds to a ROS package """ current_input = self.entry_edit_line.text() ros_pkg = rospkg.get_package_name(current_input) is_valid = current_input and os.path.isdir( current_input) and ros_pkg is not None or not current_input self.update_valid_input((current_input, ros_pkg), is_valid and current_input != "")
def get_package_and_file(argv): if not argv[1:]: usage(argv[0]) files = [a for a in argv[1:] if not a.startswith('--')] # rospy.cmake only passes in a single file arg, assert this case assert len(files) == 1, files msg_file = files[0] package = rospkg.get_package_name(msg_file) return package, msg_file
def check_input_validity(self): """ Check that the format of the current text corresponds to a file ending with .launch and is part of a ROS pkg """ current_input = self.entry_edit_line.text() is_extension_valid = current_input.endswith(".launch") ros_pkg = rospkg.get_package_name(current_input) is_valid = current_input and is_extension_valid and ros_pkg is not None and os.path.exists( current_input) self.update_valid_input((current_input, ros_pkg), is_valid and current_input != "")
def GetCompilationDatabaseFolder(ros_workspace, filename): """Return the directory potentially containing compilation_commands.json Return the absolute path to the folder (NOT the file!) containing the compile_commands.json file to use that instead of 'flags'. See here for more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html. The compilation_commands.json for the given file is returned by getting the package the file belongs to. """ pkg_name = rospkg.get_package_name(filename) if not pkg_name: return '' return os.path.join(ros_workspace, 'build', pkg_name)
def __init__(self): self.rospack = rospkg.RosPack() PACKAGE_NAME = rospkg.get_package_name(inspect.getfile(inspect.currentframe())) PACKAGE_PATH = self.rospack.get_path(PACKAGE_NAME) DOCUMENTATION_FOLDER = "pkg_documentation" self.DOCUMENTATION_PATH = os.path.join(PACKAGE_PATH, DOCUMENTATION_FOLDER) self.EXTENSION = '.rst' self.DOC = "_doc" self.CONFIG_FILENAME = "conf.py" self.MAIN_RST_FILE = os.path.join(self.DOCUMENTATION_PATH, 'pkg' + self.DOC + self.EXTENSION) self.CONFIG_FILE = os.path.join(PACKAGE_PATH, 'src', self.CONFIG_FILENAME) self.MAIN_CONF_FILE = os.path.join(PACKAGE_PATH , self.CONFIG_FILENAME ) self.packages = parse_manifest_file(PACKAGE_PATH, "manifest.xml").depends self.PACKAGES_MAP = {}
def try_find_ros_compilation_database(filename): try: from catkin_tools.metadata import find_enclosing_workspace from catkin_tools.context import Context import rospkg workspace = find_enclosing_workspace(filename) ctx = Context.load(workspace, {}, {}, load_env=False) package = rospkg.get_package_name(filename) path = os.path.join(ctx.build_space_abs, package) candidate = os.path.join(path, 'compile_commands.json') if os.path.isfile(candidate) or os.path.isdir(candidate): logging.info("Found ROS compilation database for " + filename + " at " + candidate) return candidate except: pass return None
def __init__(self, exe, args, retry=0, time_limit=None, test_name=None, text_mode=False, package_name=None): """ @param exe: path to executable to run @type exe: str @param args: arguments to exe @type args: [str] @type retry: int @param time_limit: (optional) time limit for test. Defaults to BARE_TIME_LIMIT. @type time_limit: float @param test_name: (optional) override automatically generated test name @type test_name: str @param package_name: (optional) override automatically inferred package name @type package_name: str """ super(BareTestCase, self).__init__() self.text_mode = text_mode if package_name: self.package = package_name else: self.package = rospkg.get_package_name(exe) self.exe = os.path.abspath(exe) if test_name is None: self.test_name = os.path.basename(exe) else: self.test_name = test_name # invoke pyunit tests with python executable if self.exe.endswith('.py'): self.args = ['python', self.exe] + args else: self.args = [self.exe] + args if text_mode: self.args = self.args + ['--text'] self.retry = retry self.time_limit = time_limit or BARE_TIME_LIMIT self.pmon = None self.results = junitxml.Result(self.test_name)
def calculate_missing(base_pkg, missing, file_deps, use_test_depends=False): """ Calculate missing package dependencies in the manifest. This is mainly used as a subroutine of roslaunch_deps(). @param base_pkg: name of package where initial walk begins (unused). @type base_pkg: str @param missing: dictionary mapping package names to set of missing package dependencies. @type missing: { str: set(str) } @param file_deps: dictionary mapping launch file names to RoslaunchDeps of each file @type file_deps: { str: RoslaunchDeps} @param use_test_depends [bool]: use test_depends as installed package @type use_test_depends: [bool] @return: missing (see parameter) @rtype: { str: set(str) } """ rospack = rospkg.RosPack() for launch_file in file_deps.keys(): pkg = rospkg.get_package_name( os.path.dirname(os.path.abspath(launch_file))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]" % pkg, file=sys.stderr) continue m = rospack.get_manifest(pkg) d_pkgs = set([d.name for d in m.depends]) if m.is_catkin: # for catkin packages consider the run dependencies instead # else not released packages will not appear in the dependency list # since rospkg does uses rosdep to decide which dependencies to return from catkin_pkg.package import parse_package p = parse_package(os.path.dirname(m.filename)) d_pkgs = set([d.name for d in p.run_depends]) if use_test_depends: for d in p.test_depends: d_pkgs.add(d.name) # make sure we don't count ourselves as a dep d_pkgs.add(pkg) diff = list(set(file_deps[launch_file].pkgs) - d_pkgs) if not pkg in missing: missing[pkg] = set() missing[pkg].update(diff) return missing
def btn_open_mesh_clicked(self): path = QtWidgets.QFileDialog.getOpenFileName(None, 'Open Mesh', '/home', 'Mesh Files (*.stl)')[0] try: rospackage = rospkg.get_package_name(path) if rospackage is None: QtWidgets.QMessageBox.warning( self.widget, "Saving absolute path to mesh", "Cannot find rospackage with selected mesh in it!\nSaving absolute path to mesh instead!" ) #print("WARNING cannot find rospackage with mesh in it, saving absolute path") self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "package", "")) self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "path", path)) else: rel_path = os.path.relpath( path, rospkg.RosPack().get_path(rospackage)) print("Saving: package: {} + relative path: {}".format( rospackage, rel_path)) self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "package", rospackage)) self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "path", rel_path)) except: QtWidgets.QMessageBox.warning( self.widget, "Saving absolute path to mesh", "The found rospackage with selected mesh in it is not sourced in your ROS workspace!\n" + "Cannot resolve the packagepath\nSaving absolute path to mesh instead!" ) #print("The package found is not sourced withing the current workspace, saving absolute path instead!") self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "package", "")) self.editor.command( Command_SetGeometry(self.editor, self.editor.active_frame, "path", path))
def calculate_missing(base_pkg, missing, file_deps, use_test_depends=False): """ Calculate missing package dependencies in the manifest. This is mainly used as a subroutine of roslaunch_deps(). @param base_pkg: name of package where initial walk begins (unused). @type base_pkg: str @param missing: dictionary mapping package names to set of missing package dependencies. @type missing: { str: set(str) } @param file_deps: dictionary mapping launch file names to RoslaunchDeps of each file @type file_deps: { str: RoslaunchDeps} @param use_test_depends [bool]: use test_depends as installed package @type use_test_depends: [bool] @return: missing (see parameter) @rtype: { str: set(str) } """ rospack = rospkg.RosPack() for launch_file in file_deps.keys(): pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(launch_file))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]"%pkg, file=sys.stderr) continue m = rospack.get_manifest(pkg) d_pkgs = set([d.name for d in m.depends]) if m.is_catkin: # for catkin packages consider the run dependencies instead # else not released packages will not appear in the dependency list # since rospkg does uses rosdep to decide which dependencies to return from catkin_pkg.package import parse_package p = parse_package(os.path.dirname(m.filename)) d_pkgs = set([d.name for d in p.run_depends]) if use_test_depends: for d in p.test_depends: d_pkgs.add(d.name) # make sure we don't count ourselves as a dep d_pkgs.add(pkg) diff = list(set(file_deps[launch_file].pkgs) - d_pkgs) if not pkg in missing: missing[pkg] = set() missing[pkg].update(diff) return missing
def check_main(): if len(sys.argv) < 2: usage() if "--rostest" in sys.argv[1:]: if len(sys.argv) != 4: usage() test_pkg, test_file = [a for a in sys.argv[1:] if a != "--rostest"] # this logic derives the output filename that rostest uses r = rospkg.RosPack() pkg_name = rospkg.get_package_name(test_file) pkg_dir = r.get_path(pkg_name) # compute test name for friendlier reporting outname = rosunit.rostest_name_from_path(pkg_dir, test_file) test_file = rosunit.xml_results_file(test_pkg, outname, is_rostest=True) else: if len(sys.argv) != 2: usage() test_file = sys.argv[1] print("Checking for test results in %s" % test_file) if not os.path.exists(test_file): if not os.path.exists(os.path.dirname(test_file)): os.makedirs(os.path.dirname(test_file)) print("Cannot find results, writing failure results to", test_file) with open(test_file, "w") as f: test_name = os.path.basename(test_file) d = {"test": test_name, "test_file": test_file} f.write( """<?xml version="1.0" encoding="UTF-8"?> <testsuite tests="1" failures="1" time="1" errors="0" name="%(test)s"> <testcase name="test_ran" status="run" time="1" classname="Results"> <failure message="Unable to find test results for %(test)s, test did not run.\nExpected results in %(test_file)s" type=""/> </testcase> </testsuite>""" % d )
def check_main(): if len(sys.argv) < 2: usage() if '--rostest' in sys.argv[1:]: if len(sys.argv) != 4: usage() test_pkg, test_file = [a for a in sys.argv[1:] if a != '--rostest'] # this logic derives the output filename that rostest uses r = rospkg.RosPack() pkg_name = rospkg.get_package_name(test_file) pkg_dir = r.get_path(pkg_name) # compute test name for friendlier reporting outname = rosunit.rostest_name_from_path(pkg_dir, test_file) test_file = rosunit.xml_results_file(test_pkg, outname, is_rostest=True) else: if len(sys.argv) != 2: usage() test_file = sys.argv[1] print('Checking for test results in %s' % test_file) if not os.path.exists(test_file): if not os.path.exists(os.path.dirname(test_file)): os.makedirs(os.path.dirname(test_file)) print('Cannot find results, writing failure results to', test_file) with open(test_file, 'w') as f: test_name = os.path.basename(test_file) d = {'test': test_name, 'test_file': test_file} f.write("""<?xml version="1.0" encoding="UTF-8"?> <testsuite tests="1" failures="1" time="1" errors="0" name="%(test)s"> <testcase name="test_ran" status="run" time="1" classname="Results"> <failure message="Unable to find test results for %(test)s, test did not run.\nExpected results in %(test_file)s" type=""/> </testcase> </testsuite>""" % d)
def __init__(self): # load params for this robot/client into dict self.client_params = rospy.get_param('/client_params') print(self.client_params) print('Action Server Init') # Active/Primary Task server self.feedback_sub = rospy.Subscriber( '~active_feedback', String, self.update_active_feedback) self._action_name = name self._as = actionlib.SimpleActionServer( "~active", TaskAction, execute_cb=self.execute_cb, auto_start=False) self._as.start() # Continous Task tracking/server self.running_continuous_tasks = {} self.continuous_lock = threading.RLock() self._as_continuous = actionlib.ActionServer( "~continuous", TaskAction, self.start_continuous_task, self.stop_continuous_task, auto_start=False) self._as_continuous.start() print('connecting to own action interfaces...') self.continuous_client = actionlib.ActionClient( '~/continuous', TaskAction) self.continuous_client.wait_for_server() # find the workspace so we can get tasks later current_path = os.path.abspath(__file__) pkg_name = rospkg.get_package_name(current_path) ws_name = current_path.split('src/')[0] self.ws_name = ws_name[:-1]
def print_deps(base_pkg, file_deps, verbose): pkgs = [] # for verbose output we print extra source information if verbose: for f, deps in file_deps.items(): for p, t in deps.nodes: print("%s [%s/%s]"%(p, p, t)) pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(f))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]"%pkg, file=sys.stderr) else: print("%s [%s]"%(pkg, f)) print('-'*80) # print out list of package dependencies pkgs = [] for deps in file_deps.values(): pkgs.extend(deps.pkgs) # print space-separated to be friendly to rosmake print(' '.join([p for p in set(pkgs)]))
def print_deps(base_pkg, file_deps, verbose): pkgs = [] # for verbose output we print extra source information if verbose: for f, deps in file_deps.iteritems(): for p, t in deps.nodes: print("%s [%s/%s]"%(p, p, t)) pkg = rospkg.get_package_name(os.path.dirname(os.path.abspath(f))) if pkg is None: #cannot determine package print("ERROR: cannot determine package for [%s]"%pkg, file=sys.stderr) else: print("%s [%s]"%(pkg, f)) print('-'*80) # print out list of package dependencies pkgs = [] for deps in file_deps.itervalues(): pkgs.extend(deps.pkgs) # print space-separated to be friendly to rosmake print(' '.join([p for p in set(pkgs)]))
def GetCompilationDatabaseFolder(filename): """Return the directory potentially containing compilation_commands.json Return the absolute path to the folder (NOT the file!) containing the compile_commands.json file to use that instead of 'flags'. See here for more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html. The compilation_commands.json for the given file is returned by getting the package the file belongs to. """ try: import rospkg except ImportError: return '' pkg_name = rospkg.get_package_name(filename) if not pkg_name: return '' dir = (os.path.expandvars('$ROS_WORKSPACE') + os.path.sep + 'build' + os.path.sep + pkg_name) return dir
def __parseRosParam(self, rosparam): """Parse the rosparam tag from a launch file. * rosparam -- the rosparam tag """ # Load is the default command if it is not provided command = rosparam.attrib.get(self.CommandAttribute, self.LoadCommand) # The file attribute is only valid for load and dump commands if command in [self.LoadCommand, self.DumpCommand]: paramFile = rosparam.attrib.get(self.FileAttribute, None) if paramFile is not None: # Resolve the path to the included file resolved = self.__resolveText(paramFile) # If the filename contained any arg substitutions then we # want to label the edge indicating the arg and value that # was used to conditionally select this rosparam file argSubs = {} # The file does not use any arg substitutions if resolved != paramFile: # Get the dictionary of arg substitutions that # this filename contains argSubs = self.__getSubstitutionArgs(paramFile) # Determine what ROS package contains the rosparam file package = rospkg.get_package_name(resolved) if package is None: print "ERROR: Failed to find package for rosparam " "file: %s" % resolved return # Skip the file # Create a unique name for the dot node name = basename(resolved) cleanName = name.replace(".", "_") dotNodeName = "yaml_%s_%s" % (package, cleanName) param = RosParam(resolved, name, dotNodeName, package, argSubs) self.__rosParamFiles.append(param)
def get_file_dependencies(f, stdout=sys.stdout, stderr=sys.stderr): """ Compute dependencies of the specified message/service file @param f: message or service file to get dependencies for @type f: str @param stdout pipe: stdout pipe @type stdout: file @param stderr pipe: stderr pipe @type stderr: file @return: 'files': list of files that \a file depends on, 'deps': list of dependencies by type, 'spec': Msgs/Srvs instance. @rtype: dict """ package = rospkg.get_package_name(f) spec = None if f.endswith(roslib.msgs.EXT): _, spec = roslib.msgs.load_from_file(f) elif f.endswith(roslib.srvs.EXT): _, spec = roslib.srvs.load_from_file(f) else: raise Exception("[%s] does not appear to be a message or service"%spec) return get_dependencies(spec, package, stdout, stderr)
def _parse_arguments(): ''' @raise IOError : if no package name is given and the rocon launcher cannot be found on the filesystem. ''' parser = argparse.ArgumentParser(description=help_string(), formatter_class=RawTextHelpFormatter) parser.add_argument('package', nargs='?', default=None, help='name of the package in which to find the test configuration') parser.add_argument('test', nargs=1, help='name of the test configuration (xml) file') parser.add_argument('-l', '--launch', action='store_true', help='launch each component with rocon_launch [false]') parser.add_argument('-p', '--pause', action='store_true', help='pause before tearing down so you can introspect easily [false]') parser.add_argument('-s', '--screen', action='store_true', help='run each roslaunch with the --screen option') parser.add_argument('-t', '--text-mode', action='store_true', help='log the rostest output to screen rather than log file.') args = parser.parse_args() # Stop it from being a list (happens when nargs is an integer) args.test = args.test[0] if args.screen: args.screen = "--screen" else: args.screen = "" if not args.package: if not os.path.isfile(args.test): raise IOError("Test launcher file does not exist [%s]." % args.test) else: args.package = rospkg.get_package_name(args.test) return (args.package, args.test, args.screen, args.pause, args.text_mode)
def rostestmain(): import roslaunch.rlutil from optparse import OptionParser parser = OptionParser(usage="usage: %prog [options] [package] <filename>", prog=_NAME) parser.add_option("-t", "--text", action="store_true", dest="text_mode", default=False, help="Run with stdout output instead of XML output") parser.add_option("--pkgdir", metavar="PKG_DIR", dest="pkg_dir", default=None, help="package dir") parser.add_option("--package", metavar="PACKAGE", dest="package", default=None, help="package") parser.add_option("--results-filename", metavar="RESULTS_FILENAME", dest="results_filename", default=None, help="results_filename") parser.add_option("--results-base-dir", metavar="RESULTS_BASE_DIR", help="The base directory of the test results. The test result file is " + "created in a subfolder name PKG_DIR.") (options, args) = parser.parse_args() try: args = roslaunch.rlutil.resolve_launch_arguments(args) except roslaunch.core.RLException as e: print(str(e), file=sys.stderr) sys.exit(1) # make sure all loggers are configured properly logfile_name = configure_logging() logger = logging.getLogger('rostest') import roslaunch.core roslaunch.core.add_printlog_handler(logger.info) roslaunch.core.add_printerrlog_handler(logger.error) logger.info('rostest starting with options %s, args %s'%(options, args)) if len(args) == 0: parser.error("You must supply a test file argument to rostest.") if len(args) != 1: parser.error("rostest only accepts a single test file") # compute some common names we'll be using to generate test names and files test_file = args[0] if options.pkg_dir and options.package: # rosbuild2: the build system knows what package and directory, so let it tell us, # instead of shelling back out to rospack pkg_dir, pkg = options.pkg_dir, options.package else: pkg = rospkg.get_package_name(test_file) r = rospkg.RosPack() pkg_dir = r.get_path(pkg) if options.results_filename: outname = options.results_filename if '.' in outname: outname = outname[:outname.rfind('.')] else: outname = rostest_name_from_path(pkg_dir, test_file) env = None if options.results_base_dir: env = {ROS_TEST_RESULTS_DIR: options.results_base_dir} # #1140 if not os.path.isfile(test_file): results_file = xmlResultsFile(pkg, outname, True, env=env) write_bad_filename_failure(test_file, results_file, outname) parser.error("test file is invalid. Generated failure case result file in %s"%results_file) try: testCase = rostest.runner.createUnitTest(pkg, test_file) suite = unittest.TestLoader().loadTestsFromTestCase(testCase) if options.text_mode: rostest.runner.setTextMode(True) result = unittest.TextTestRunner(verbosity=2).run(suite) else: is_rostest = True results_file = xmlResultsFile(pkg, outname, is_rostest, env=env) xml_runner = createXMLRunner(pkg, outname, \ results_file=results_file, \ is_rostest=is_rostest) result = xml_runner.run(suite) finally: # really make sure that all of our processes have been killed test_parents = rostest.runner.getRostestParents() for r in test_parents: logger.info("finally rostest parent tearDown [%s]", r) r.tearDown() del test_parents[:] from roslaunch.pmon import pmon_shutdown logger.info("calling pmon_shutdown") pmon_shutdown() logger.info("... done calling pmon_shutdown") # print config errors after test has run so that we don't get caught up in .xml results config = rostest.runner.getConfig() if config: if config.config_errors: print("\n[ROSTEST WARNINGS]"+'-'*62+'\n', file=sys.stderr) for err in config.config_errors: print(" * %s"%err, file=sys.stderr) print('') # summary is worthless if textMode is on as we cannot scrape .xml results subtest_results = rostest.runner.getResults() if not options.text_mode: printRostestSummary(result, subtest_results) else: print("WARNING: overall test result is not accurate when --text is enabled") if logfile_name: print("rostest log file is in %s"%logfile_name) if not result.wasSuccessful(): sys.exit(1) elif subtest_results.num_errors or subtest_results.num_failures: sys.exit(2)
parser.add_option("-o", "--output-file", dest="output_file", default=None, help="file to store test results in", metavar="FILE") options, args = parser.parse_args() if not args: parser.error('please specify a file or directory for roslaunch files to test') roslaunch_path = args[0] # #2590: implementing this quick and dirty as this script should only be used by higher level tools env_vars = args[1:] for e in env_vars: var, val = e.split('=') os.environ[var] = val pkg = rospkg.get_package_name(roslaunch_path) r = rospkg.RosPack() pkg_dir = r.get_path(pkg) if os.path.isfile(roslaunch_path): error_msg = check_roslaunch_file(roslaunch_path) outname = os.path.basename(roslaunch_path).replace('.', '_') else: print("checking *.launch in directory", roslaunch_path) error_msg = check_roslaunch_dir(roslaunch_path) abspath = os.path.abspath relpath = abspath(roslaunch_path)[len(abspath(pkg_dir))+1:] outname = relpath.replace(os.sep, '_') if outname == '.': outname = '_pkg'
def rosunitmain(): from optparse import OptionParser parser = OptionParser(usage="usage: %prog [options] <file> [test args...]", prog=_NAME) parser.add_option("-t", "--text", action="store_true", dest="text_mode", default=False, help="Run with stdout output instead of XML output") parser.add_option("--time-limit", metavar="TIME_LIMIT", dest="time_limit", default=60, help="Set time limit for test") parser.add_option("--name", metavar="TEST_NAME", dest="test_name", default=None, help="Test name") parser.add_option("--package", metavar="PACKAGE_NAME", dest="pkg", default=None, help="Package name (optional)") (options, args) = parser.parse_args() if len(args) < 1: parser.error("You must supply a test file.") test_file = args[0] if options.test_name: test_name = options.test_name else: test_name = os.path.basename(test_file) if '.' in test_name: test_name = test_name[:test_name.rfind('.')] time_limit = float(options.time_limit) if options.time_limit else None # If the caller didn't tell us the package name, we'll try to infer it. # compute some common names we'll be using to generate test names and files pkg = options.pkg if not pkg: pkg = rospkg.get_package_name(test_file) if not pkg: print("Error: failed to determine package name for file '%s'; maybe you should supply the --package argument to rosunit?"%(test_file)) sys.exit(1) try: runner_result = None results = Result('rosunit', 0, 0, 0) test_case = BareTestCase(test_file, args[1:], \ retry=0, time_limit=time_limit, \ test_name=test_name, text_mode=options.text_mode, package_name=pkg) suite = unittest.TestSuite() suite.addTest(test_case) if options.text_mode: result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite) else: results_file = xml_results_file(pkg, test_name, True) # the is_rostest really just means "wrapper" xml_runner = create_xml_runner(pkg, test_name, \ results_file=results_file, \ is_rostest=True) runner_result = xml_runner.run(suite) finally: pmon.pmon_shutdown() # summary is worthless if textMode is on as we cannot scrape .xml results results = test_case.results if not options.text_mode: print_runner_summary(runner_result, results) else: print("WARNING: overall test result is not accurate when --text is enabled") if runner_result is not None and not runner_result.wasSuccessful(): sys.exit(1) elif results.num_errors or results.num_failures: sys.exit(2)
def check_roslaunch(f): """ Check roslaunch file for errors, returning error message if check fails. This routine is mainly to support rostest's roslaunch_check. :param f: roslaunch file name, ``str`` :returns: error message or ``None`` """ try: rl_config = roslaunch.config.load_config_default([f], DEFAULT_MASTER_PORT, verbose=False) except roslaunch.core.RLException as e: return str(e) rospack = rospkg.RosPack() errors = [] # check for missing deps try: base_pkg, file_deps, missing = roslaunch.depends.roslaunch_deps([f]) except rospkg.common.ResourceNotFound as r: errors.append("Could not find package [%s] included from [%s]"%(str(r), f)) missing = {} file_deps = {} except roslaunch.substitution_args.ArgException as e: errors.append("Could not resolve arg [%s] in [%s]"%(str(e), f)) missing = {} file_deps = {} for pkg, miss in missing.items(): # even if the pkgs is not found in packges.xml, if other package.xml provdes that pkgs, then it will be ok all_pkgs = [] try: for file_dep in file_deps.keys(): file_pkg = rospkg.get_package_name(file_dep) all_pkgs.extend(rospack.get_depends(file_pkg,implicit=False)) miss_all = list(set(miss) - set(all_pkgs)) except Exception as e: print(e, file=sys.stderr) miss_all = True if miss_all: print("Missing package dependencies: %s/package.xml: %s"%(pkg, ', '.join(miss)), file=sys.stderr) errors.append("Missing package dependencies: %s/package.xml: %s"%(pkg, ', '.join(miss))) elif miss: print("Missing package dependencies: %s/package.xml: %s (notify upstream maintainer)"%(pkg, ', '.join(miss)), file=sys.stderr) # load all node defs nodes = [] for filename, rldeps in file_deps.items(): nodes.extend(rldeps.nodes) # check for missing packages for pkg, node_type in nodes: try: rospack.get_path(pkg) except: errors.append("cannot find package [%s] for node [%s]"%(pkg, node_type)) # check for missing nodes for pkg, node_type in nodes: try: if not roslib.packages.find_node(pkg, node_type, rospack=rospack): errors.append("cannot find node [%s] in package [%s]"%(node_type, pkg)) except Exception as e: errors.append("unable to find node [%s/%s]: %s"%(pkg, node_type, str(e))) # Check for configuration errors, #2889 for err in rl_config.config_errors: errors.append('ROSLaunch config error: %s' % err) if errors: return '\n'.join(errors)
def rosunitmain(): from optparse import OptionParser parser = OptionParser(usage="usage: %prog [options] <file> [test args...]", prog=_NAME) parser.add_option("-t", "--text", action="store_true", dest="text_mode", default=False, help="Run with stdout output instead of XML output") parser.add_option("--time-limit", metavar="TIME_LIMIT", dest="time_limit", default=60, help="Set time limit for test") parser.add_option("--name", metavar="TEST_NAME", dest="test_name", default=None, help="Test name") parser.add_option("--package", metavar="PACKAGE_NAME", dest="pkg", default=None, help="Package name (optional)") (options, args) = parser.parse_args() if len(args) < 1: parser.error("You must supply a test file.") test_file = args[0] if options.test_name: test_name = options.test_name else: test_name = os.path.basename(test_file) if '.' in test_name: test_name = test_name[:test_name.rfind('.')] time_limit = float(options.time_limit) if options.time_limit else None # If the caller didn't tell us the package name, we'll try to infer it. # compute some common names we'll be using to generate test names and files pkg = options.pkg if not pkg: pkg = rospkg.get_package_name(test_file) if not pkg: print "Error: failed to determine package name for file '%s'; maybe you should supply the --package argument to rosunit?"%(test_file) sys.exit(1) try: runner_result = None results = Result('rosunit', 0, 0, 0) test_case = BareTestCase(test_file, args[1:], \ retry=0, time_limit=time_limit, \ test_name=test_name, text_mode=options.text_mode, package_name=pkg) suite = unittest.TestSuite() suite.addTest(test_case) if options.text_mode: result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(suite) else: results_file = xml_results_file(pkg, test_name, True) # the is_rostest really just means "wrapper" xml_runner = create_xml_runner(pkg, test_name, \ results_file=results_file, \ is_rostest=True) runner_result = xml_runner.run(suite) finally: pmon.pmon_shutdown() # summary is worthless if textMode is on as we cannot scrape .xml results results = test_case.results if not options.text_mode: print_runner_summary(runner_result, results) else: print "WARNING: overall test result is not accurate when --text is enabled" if runner_result is not None and not runner_result.wasSuccessful(): sys.exit(1) elif results.num_errors or results.num_failures: sys.exit(2)
def rostestmain(): import roslaunch.rlutil from optparse import OptionParser parser = OptionParser(usage="usage: %prog [options] [package] <filename>", prog=_NAME) parser.add_option("-t", "--text", action="store_true", dest="text_mode", default=False, help="Run with stdout output instead of XML output") parser.add_option("--pkgdir", metavar="PKG_DIR", dest="pkg_dir", default=None, help="package dir") parser.add_option("--package", metavar="PACKAGE", dest="package", default=None, help="package") parser.add_option("--results-filename", metavar="RESULTS_FILENAME", dest="results_filename", default=None, help="results_filename") (options, args) = parser.parse_args() try: args = roslaunch.rlutil.resolve_launch_arguments(args) except roslaunch.core.RLException as e: print(str(e), file=sys.stderr) sys.exit(1) # make sure all loggers are configured properly logfile_name = configure_logging() logger = logging.getLogger('rostest') import roslaunch.core roslaunch.core.add_printlog_handler(logger.info) roslaunch.core.add_printerrlog_handler(logger.error) logger.info('rostest starting with options %s, args %s'%(options, args)) if len(args) == 0: parser.error("You must supply a test file argument to rostest.") if len(args) != 1: parser.error("rostest only accepts a single test file") # compute some common names we'll be using to generate test names and files test_file = args[0] if options.pkg_dir and options.package: # rosbuild2: the build system knows what package and directory, so let it tell us, # instead of shelling back out to rospack pkg_dir, pkg = options.pkg_dir, options.package else: pkg = rospkg.get_package_name(test_file) r = rospkg.RosPack() pkg_dir = r.get_path(pkg) if options.results_filename: outname = options.results_filename if '.' in outname: outname = outname[:outname.rfind('.')] else: outname = rostest_name_from_path(pkg_dir, test_file) # #1140 if not os.path.isfile(test_file): results_file = xmlResultsFile(pkg, outname, True) write_bad_filename_failure(test_file, results_file, outname) parser.error("test file is invalid. Generated failure case result file in %s"%results_file) try: testCase = rostest.runner.createUnitTest(pkg, test_file) suite = unittest.TestLoader().loadTestsFromTestCase(testCase) if options.text_mode: rostest.runner.setTextMode(True) result = unittest.TextTestRunner(verbosity=2).run(suite) else: is_rostest = True results_file = xmlResultsFile(pkg, outname, is_rostest) xml_runner = createXMLRunner(pkg, outname, \ results_file=results_file, \ is_rostest=is_rostest) result = xml_runner.run(suite) finally: # really make sure that all of our processes have been killed test_parents = rostest.runner.getRostestParents() for r in test_parents: logger.info("finally rostest parent tearDown [%s]", r) r.tearDown() del test_parents[:] from roslaunch.pmon import pmon_shutdown logger.info("calling pmon_shutdown") pmon_shutdown() logger.info("... done calling pmon_shutdown") # print config errors after test has run so that we don't get caught up in .xml results config = rostest.runner.getConfig() if config: if config.config_errors: print("\n[ROSTEST WARNINGS]"+'-'*62+'\n', file=sys.stderr) for err in config.config_errors: print(" * %s"%err, file=sys.stderr) print('') # summary is worthless if textMode is on as we cannot scrape .xml results subtest_results = rostest.runner.getResults() if not options.text_mode: printRostestSummary(result, subtest_results) else: print("WARNING: overall test result is not accurate when --text is enabled") if logfile_name: print("rostest log file is in %s"%logfile_name) if not result.wasSuccessful(): sys.exit(1) elif subtest_results.num_errors or subtest_results.num_failures: sys.exit(2)
def _roswtf_main(): launch_files = names = None # performance optimization rospack = rospkg.RosPack() all_pkgs = rospack.list() import optparse parser = optparse.OptionParser(usage="usage: roswtf [launch file]", description="roswtf is a tool for verifying a ROS installation and running system. Checks provided launchfile if provided, else current stack or package.") # #2268 parser.add_option("--all", dest="all_packages", default=False, action="store_true", help="run roswtf against all packages") # #2270 parser.add_option("--no-plugins", dest="disable_plugins", default=False, action="store_true", help="disable roswtf plugins") parser.add_option("--offline", dest="offline", default=False, action="store_true", help="only run offline tests") #TODO: --all-pkgs option options, args = parser.parse_args() if args: launch_files = args if 0: # disable names for now as don't have any rules yet launch_files = [a for a in args if os.path.isfile(a)] names = [a for a in args if not a in launch_files] names = [rosgraph.names.script_resolve_name('/roswtf', n) for n in names] from roswtf.context import WtfContext from roswtf.environment import wtf_check_environment, invalid_url, ros_root_check from roswtf.graph import wtf_check_graph import roswtf.network import roswtf.packages import roswtf.roslaunchwtf import roswtf.stacks import roswtf.plugins if not options.disable_plugins: static_plugins, online_plugins = roswtf.plugins.load_plugins() else: static_plugins, online_plugins = [], [] # - do a ros_root check first and abort if it fails as rest of tests are useless after that error = ros_root_check(None, ros_root=os.environ['ROS_ROOT']) if error: print "ROS_ROOT is invalid: "+str(error) sys.exit(1) all_warnings = [] all_errors = [] if launch_files: ctx = WtfContext.from_roslaunch(launch_files) #TODO: allow specifying multiple roslaunch files else: curr_package = rospkg.get_package_name('.') if curr_package: print "Package:",curr_package ctx = WtfContext.from_package(curr_package) #TODO: load all .launch files in package elif os.path.isfile('stack.xml'): curr_stack = os.path.basename(os.path.abspath('.')) print "Stack:",curr_stack ctx = WtfContext.from_stack(curr_stack) else: print "No package or stack in context" ctx = WtfContext.from_env() if options.all_packages: print "roswtf will run against all packages" ctx.pkgs = all_pkgs # static checks wtf_check_environment(ctx) roswtf.network.wtf_check(ctx) roswtf.packages.wtf_check(ctx) roswtf.stacks.wtf_check(ctx) roswtf.roslaunchwtf.wtf_check_static(ctx) for p in static_plugins: p(ctx) print "="*80 print "Static checks summary:\n" print_results(ctx) # Save static results and start afresh for online checks all_warnings.extend(ctx.warnings) all_errors.extend(ctx.errors) del ctx.warnings[:] del ctx.errors[:] # test online print "="*80 try: if options.offline or not ctx.ros_master_uri or invalid_url(ctx.ros_master_uri) or not rosgraph.is_master_online(): online_checks = False else: online_checks = True if online_checks: online_checks = True print "Beginning tests of your ROS graph. These may take awhile..." # online checks wtf_check_graph(ctx, names=names) elif names: # TODO: need to rework this logic print "\nCannot communicate with master, unable to diagnose [%s]"%(', '.join(names)) return else: print "\nROS Master does not appear to be running.\nOnline graph checks will not be run.\nROS_MASTER_URI is [%s]"%(ctx.ros_master_uri) return # spin up a roswtf node so we can subscribe to messages import rospy rospy.init_node('roswtf', anonymous=True) online_checks = True roswtf.roslaunchwtf.wtf_check_online(ctx) for p in online_plugins: online_checks = True p(ctx) if online_checks: # done print "\nOnline checks summary:\n" print_results(ctx) except roswtf.context.WtfException, e: print >> sys.stderr, str(e) print "\nAborting checks, partial results summary:\n" print_results(ctx)