def dictpath(dictionary, path): """Traverse a path in a nested dict""" index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') for component in path.split('/'): match = index_re.match(component) if match: component, idx = match.groups() idx = int(idx) if not isinstance(dictionary, dict) or component not in dictionary: raise QMPError('failed path traversal for "%s" in "%s"' % (path, str(dictionary))) dictionary = dictionary[component] if match: if not isinstance(dictionary, list): raise QMPError( 'path component "%s" in "%s" is not a list in "%s"' % (component, path, str(dictionary))) try: dictionary = dictionary[idx] except IndexError: raise QMPError('invalid index "%s" in path "%s" in "%s"' % (idx, path, str(dictionary))) return dictionary
def assert_qmp_absent(dictionary, path): """Assert that the path is invalid in 'dictionary'""" try: result = dictpath(dictionary, path) except AssertionError: return raise QMPError('path "%s" has value "%s"' % (path, str(result)))
def qmp_command(self, cmd, **args): """Run qmp command""" qmp_dict = dict() for key, value in args.items(): if key.find("_") != -1: qmp_dict[key.replace('_', '-')] = value else: qmp_dict[key] = value rep = self._cmd(cmd, args=qmp_dict) if rep is None: raise QMPError("Monitor was closed") return rep
def assert_qmp(dictionary, path, value): """ Assert that the value for a specific path in a QMP dict matches. When given a list of values, assert that any of them matches. """ result = dictpath(dictionary, path) # [] makes no sense as a list of valid values, so treat it as # an actual single value. if isinstance(value, list) and value != []: for val in value: if result == val: return raise QMPError('no match for "%s" in %s' % (str(result), str(value))) assert result == value