def test_eq(self): # Copy tree2 = copy.deepcopy(self.tree) self.assertEqual(self.tree, tree2) # Additional node child = tree.TreeNode("20", {'name': 'Heisenbug'}) tree2.children[1].children[1].add_child(child) self.assertNotEqual(self.tree, tree2) # Should match again child.detach() self.assertEqual(self.tree, tree2) # Missing node tree2.children[1].children[1].detach() self.assertNotEqual(self.tree, tree2) self.assertEqual(self.tree.children[0], tree2.children[0]) # Different value tree2.children[0].children[0].children[0].value = {'something': 'else'} self.assertNotEqual(self.tree.children[0], tree2.children[0]) tree3 = tree.TreeNode() self.assertNotEqual(tree3, tree2) # Merge tree3.merge(tree2) self.assertEqual(tree3, tree2) # Add_child existing tree3.add_child(tree2.children[0]) self.assertEqual(tree3, tree2)
def test_eq_value(self): self.assertEqual(tree.TreeNode(value={"same": "same"}), tree.TreeNode(value={"same": "same"})) self.assertNotEqual( tree.TreeNode(value={"same": "same"}), tree.TreeNode(value={"same": "other"}), )
def test_same_origin_of_different_nodes(self): # ideally we have one tree, therefor shared key # have identical origin (id of the origin env) foo = tree.TreeNode().get_node("/foo", True) root = foo.parent root.value = {'timeout': 1} bar = root.get_node("/bar", True) params1 = parameters.AvocadoParams([foo, bar], '/') self.assertEqual(params1.get('timeout'), 1) self.assertEqual(params1.get('timeout', '/foo/'), 1) self.assertEqual(params1.get('timeout', '/bar/'), 1) # Sometimes we get multiple trees, but if they claim the origin # is of the same path, let's trust it (even when the values # differ) # note: This is an artificial example which should not happen # in production. Anyway in json-variants-loader we do create # only leave-nodes without connecting the parents, which result # in same paths with different node objects. Let's make sure # they behave correctly. baz = tree.TreeNode().get_node("/baz", True) baz.parent.value = {'timeout': 2} params2 = parameters.AvocadoParams([foo, baz], '/') self.assertEqual(params2.get('timeout'), 1) self.assertEqual(params2.get('timeout', '/foo/'), 1) self.assertEqual(params2.get('timeout', '/baz/'), 2)
def test_children_order(self): huey = tree.TreeNode(name='Huey') dewey = tree.TreeNode(name='Dewey') louie = tree.TreeNode(name='Louie') scrooge = tree.TreeNode(name='Scrooge', children=[huey, dewey, louie]) self.assertIs(scrooge.children[0], huey) self.assertIs(scrooge.children[1], dewey) self.assertIs(scrooge.children[2], louie)
def test_children_order(self): huey = tree.TreeNode(name="Huey") dewey = tree.TreeNode(name="Dewey") louie = tree.TreeNode(name="Louie") scrooge = tree.TreeNode(name="Scrooge", children=[huey, dewey, louie]) self.assertIs(scrooge.children[0], huey) self.assertIs(scrooge.children[1], dewey) self.assertIs(scrooge.children[2], louie)
def test_fingerprint(self): self.assertEqual( tree.TreeNode("foo").fingerprint(), "/foo{},{},FilterSet([]),FilterSet([])") self.assertEqual( tree.TreeNode("bar", value={ "key": "val" }).fingerprint(), "/bar{key: val},{key: /bar},FilterSet([]),FilterSet([])")
def test_fingerprint_order(self): """ Checks whether different order changes the fingerprint """ children1 = (tree.TreeNode("child1"), tree.TreeNode("child2")) tree1 = tree.TreeNode("root", children=children1) children2 = (tree.TreeNode("child2"), tree.TreeNode("child1")) tree2 = tree.TreeNode("root", children=children2) mux1 = mux.MuxPlugin() mux2 = mux.MuxPlugin() mux1.initialize_mux(tree1, "", False) mux2.initialize_mux(tree2, "", False) mux1.update_defaults(tree.TreeNode()) mux2.update_defaults(tree.TreeNode()) variant1 = next(iter(mux1)) variant2 = next(iter(mux2)) self.assertNotEqual(variant1, variant2) str_variant = str(variant1) variant_list = [] for item in variant1: variant_list.append("'%s': '%s'" % (item, variant1[item])) expected_items = [ "'paths': ''", "'variant': '[TreeNode(name='child1'), " "TreeNode(name='child2')]'", "'variant_id': 'child1-child2-9154'" ] for item in expected_items: self.assertIn(item, variant_list) variant_list.remove(item) self.assertFalse(variant_list)
def _template_to_factory(test_parameters, template, variant): """ Applies test params from variant to the test template :param test_parameters: a simpler set of parameters (currently given to the run command via "-p" parameters) :param template: a test template, containing the class name, followed by parameters to the class :type template: tuple :param variant: variant to be applied, usually containing the keys: paths, variant and variant_id :type variant: dict :return: tuple(new_test_factory, applied_variant) """ var = variant.get("variant") paths = variant.get("paths") original_params_to_klass = template[1] if "params" not in original_params_to_klass: params_to_klass = original_params_to_klass.copy() if test_parameters: var[0] = tree.TreeNode().get_node("/", True) var[0].value = test_parameters paths = ["/"] params_to_klass["params"] = (var, paths) factory = [template[0], params_to_klass] return factory, variant return template, {"variant": var, "variant_id": varianter.generate_variant_id(var), "paths": paths}
def start(self): """ Start to parsing arguments. At the end of this method, the support for subparsers is activated. Side effect: update attribute `args` (the namespace). """ self.args, _ = self.application.parse_known_args() # Load settings from file, if user provides one if self.args.config is not None: settings.settings.process_config_path(self.args.config) # Use parent parsing to avoid breaking the output of --help option self.application = ArgumentParser(prog=PROG, description=DESCRIPTION, parents=[self.application]) # Subparsers where Avocado subcommands are plugged self.subcommands = self.application.add_subparsers( title='subcommands', description='valid subcommands', help='subcommand help', dest='subcommand') # Allow overriding default params by plugins self.args.mux = multiplexer.Mux(getattr(self.args, "mux-debug", False)) # FIXME: Backward compatibility params, to be removed when 36 LTS is # discontinued self.args.default_avocado_params = tree.TreeNode()
def is_empty_variant(variant): """ Reports whether the variant contains any data :param variant: Avocado test variant (list of TreeNode-like objects) :return: True when the variant does not contain (any useful) data """ return not variant or variant == [tree.TreeNode()] * len(variant)
def test_greedy_path_to_re(self): params = parameters.AvocadoParams([tree.TreeNode()], ["/run"]) self.assertEqual(params._greedy_path_to_re("").pattern, "^$") self.assertEqual(params._greedy_path_to_re("/").pattern, "/$") self.assertEqual( params._greedy_path_to_re("/foo/bar").pattern, "/foo/bar$") self.assertEqual( params._greedy_path_to_re("foo/bar").pattern, "foo/bar$") self.assertEqual( params._greedy_path_to_re("/*/foo").pattern, "/[^/]*/foo$") self.assertEqual(params._greedy_path_to_re("foo/*").pattern, "foo/") self.assertEqual(params._greedy_path_to_re("/foo/*").pattern, "/foo/")
def test_greedy_path_to_re(self): params = parameters.AvocadoParams([tree.TreeNode()], ['/run']) self.assertEqual(params._greedy_path_to_re('').pattern, '^$') self.assertEqual(params._greedy_path_to_re('/').pattern, '/$') self.assertEqual( params._greedy_path_to_re('/foo/bar').pattern, '/foo/bar$') self.assertEqual( params._greedy_path_to_re('foo/bar').pattern, 'foo/bar$') self.assertEqual( params._greedy_path_to_re('/*/foo').pattern, '/[^/]*/foo$') self.assertEqual(params._greedy_path_to_re('foo/*').pattern, 'foo/') self.assertEqual(params._greedy_path_to_re('/foo/*').pattern, '/foo/')
def test_fingerprint(self): """ Verifies the fingerprint is correctly evaluated """ node1 = tree.TreeNode("node1", {"foo": "bar"}) node1_fingerprint = node1.fingerprint() node1duplicate = tree.TreeNode("node1", {"foo": "bar"}) self.assertEqual(node1_fingerprint, node1duplicate.fingerprint()) node1b_value = tree.TreeNode("node1", {"foo": "baz"}) self.assertNotEqual(node1_fingerprint, node1b_value.fingerprint()) node1b_name = tree.TreeNode("node2", {"foo": "bar"}) self.assertNotEqual(node1_fingerprint, node1b_name) node1b_path = tree.TreeNode("node1", {"foo": "bar"}) tree.TreeNode("root", children=(node1b_path, )) self.assertNotEqual(node1_fingerprint, node1b_path.fingerprint()) node1b_env_orig = tree.TreeNode("node1", {"foo": "bar"}) tree.TreeNode("root", {"bar": "baz"}, children=(node1b_env_orig)) node1b_env_origb = tree.TreeNode("node1", {"foo": "bar", "bar": "baz"}) tree.TreeNode("root", children=(node1b_env_origb, )) self.assertNotEqual(node1b_env_orig.fingerprint(), node1b_env_origb.fingerprint())
def test_fingerprint_order(self): """ Checks whether different order changes the fingerprint """ children1 = (tree.TreeNode("child1"), tree.TreeNode("child2")) tree1 = tree.TreeNode("root", children=children1) children2 = (tree.TreeNode("child2"), tree.TreeNode("child1")) tree2 = tree.TreeNode("root", children=children2) mux1 = mux.MuxPlugin() mux2 = mux.MuxPlugin() mux1.initialize_mux(tree1, "") mux2.initialize_mux(tree2, "") variant1 = next(iter(mux1)) variant2 = next(iter(mux2)) self.assertNotEqual(variant1, variant2) # test variant __str__() str(variant1) variant_list = [] for item in variant1: variant_list.append(f"'{item}': '{variant1[item]}'") expected_items = [ "'paths': ''", "'variant': '[TreeNode(name='child1'), TreeNode(name='child2')]'", "'variant_id': 'child1-child2-f47e'", ] for item in expected_items: self.assertIn(item, variant_list) variant_list.remove(item) self.assertFalse(variant_list)
def test_merge_trees(self): tree2 = copy.deepcopy(self.tree) tree3 = tree.TreeNode() tree3.add_child(tree.TreeNode('hw', {'another_value': 'bbb'})) tree3.children[0].add_child(tree.TreeNode('nic')) tree3.children[0].children[0].add_child(tree.TreeNode('default')) tree3.children[0].children[0].add_child( tree.TreeNode('virtio', {'nic': 'virtio'})) tree3.children[0].add_child(tree.TreeNode('cpu', {'test_value': ['z']})) tree2.merge(tree3) exp = [ 'intel', 'amd', 'arm', 'scsi', 'virtio', 'default', 'virtio', 'fedora', 'mint', 'prod' ] self.assertEqual(exp, tree2.get_leaves()) self.assertEqual( { 'corruptlist': ['upper_node_list'], 'another_value': 'bbb' }, tree2.children[0].value) self.assertEqual({ 'joinlist': ['first_item'], 'test_value': ['z'] }, tree2.children[0].children[0].value) self.assertFalse(tree2.children[0].children[2].children[0].value) self.assertEqual({'nic': 'virtio'}, tree2.children[0].children[2].children[1].value)
def test_tree_mux_node(self): """ Check the extension of fingerprint in MuxTreeNode """ node1 = tree.TreeNode("node1", {"foo": "bar"}) node1m = mux.MuxTreeNode("node1", {"foo": "bar"}) node1m_fingerprint = node1m.fingerprint() self.assertNotEqual(node1.fingerprint(), node1m_fingerprint) node1mduplicate = mux.MuxTreeNode("node1", {"foo": "bar"}) self.assertEqual(node1m_fingerprint, node1mduplicate.fingerprint()) node1mb_ctrl = mux.MuxTreeNode("node1", {"foo": "bar"}) node1mb_ctrl.ctrl = [mux.Control(0, 0)] self.assertNotEqual(node1m_fingerprint, node1mb_ctrl.fingerprint())
def test_eq_children(self): huey = tree.TreeNode(name='Huey') dewey = tree.TreeNode(name='Dewey') louie = tree.TreeNode(name='Louie') original = tree.TreeNode(children=[huey, dewey, louie]) clone = tree.TreeNode(children=[huey, dewey, louie]) self.assertEqual(original, clone) self.assertNotEqual(original, tree.TreeNode(children=[huey, dewey]))
def check_scenario(self, *args): """ Turn args into scenario. :param *args: Definitions of variant's nodes. Each arg has to be of length 3, where on index: [0] is path [1] is filter-only [2] is filter-out """ variant = [] # Turn scenario into variant for arg in args: variant.append(tree.TreeNode().get_node(arg[0], True)) variant[-1].filters = [arg[1], arg[2]] # Check directly the MuxTree._valid_variant function return mux.MuxTree._valid_variant(variant) # pylint: disable=W0212
def test_fingerprint_order(self): """ Checks whether different order changes the fingerprint """ children1 = (tree.TreeNode("child1"), tree.TreeNode("child2")) tree1 = tree.TreeNode("root", children=children1) children2 = (tree.TreeNode("child2"), tree.TreeNode("child1")) tree2 = tree.TreeNode("root", children=children2) mux1 = mux.MuxPlugin() mux2 = mux.MuxPlugin() mux1.initialize_mux(tree1, "", False) mux2.initialize_mux(tree2, "", False) mux1.update_defaults(tree.TreeNode()) mux2.update_defaults(tree.TreeNode()) variant1 = iter(mux1).next() variant2 = iter(mux2).next() self.assertNotEqual(variant1, variant2) self.assertEqual(str(variant1), "{'mux_path': '', 'variant': " "[TreeNode(name='child1'), TreeNode(name=" "'child2')], 'variant_id': 'child1-child2-9154'}")
def _template_to_factory(test_parameters, template, variant): """ Applies test params from variant to the test template :param test_parameters: a simpler set of parameters (currently given to the run command via "-p" parameters) :param template: a test template, containing the class name, followed by parameters to the class :type template: tuple :param variant: variant to be applied, usually containing the keys: paths, variant and variant_id :type variant: dict :return: tuple(new_test_factory, applied_variant) """ var = variant.get("variant") paths = variant.get("paths") empty_variants = varianter.is_empty_variant(var) original_params_to_klass = template[1] if "params" not in original_params_to_klass: params_to_klass = original_params_to_klass.copy() if test_parameters and empty_variants: var[0] = tree.TreeNode().get_node("/", True) var[0].value = test_parameters paths = ["/"] params_to_klass["params"] = (var, paths) factory = [template[0], params_to_klass] return factory, variant if not empty_variants: raise NotImplementedError( "Specifying test params from test loader " "and from varianter at the same time is " "not yet supported. Please remove either " "variants defined by the varianter (%s) " "or make the test loader of test %s to " "not to fill variants." % (variant, template)) return template, { "variant": var, "variant_id": varianter.generate_variant_id(var), "paths": paths }
def create_from_yaml(paths, debug=False): """ Create tree structure from yaml-like file :param fileobj: File object to be processed :raise SyntaxError: When yaml-file is corrupted :return: Root of the created tree structure """ def _merge(data, path): """ Normal run """ tmp = _create_from_yaml(path) if tmp: data.merge(tmp) def _merge_debug(data, path): """ Use NamedTreeNodeDebug magic """ node_cls = tree.get_named_tree_cls(path) tmp = _create_from_yaml(path, node_cls) if tmp: data.merge(tmp) if not debug: data = tree.TreeNode() merge = _merge else: data = tree.TreeNodeDebug() merge = _merge_debug path = None try: for path in paths: merge(data, path) # Yaml can raise IndexError on some files except (yaml.YAMLError, IndexError) as details: if 'mapping values are not allowed in this context' in str(details): details = ("%s\nMake sure !tags and colons are separated by a " "space (eg. !include :)" % details) msg = "Invalid multiplex file '%s': %s" % (path, details) raise IOError(2, msg, path) return data
def test_childs_parent(self): child = tree.TreeNode() parent = tree.TreeNode(children=[child]) self.assertIs(child.parent, parent)
def test_eq_name(self): original = tree.TreeNode(name='same') clone = tree.TreeNode(name='same') self.assertEqual(original, clone) self.assertNotEqual(original, tree.TreeNode(name='other'))
def test_empty(self): act = tuple(multiplexer.MuxTree(tree.TreeNode())) self.assertEqual(act, ([ '', ], ))
def test_eq_name_str(self): original = tree.TreeNode(name='same') self.assertEqual(original, 'same') self.assertNotEqual(original, 'other')
def test_empty(self): act = tuple(combine(multiplexer.tree2pools(tree.TreeNode()))) self.assertEqual(act, ((),))
def test_eq_value(self): self.assertEqual(tree.TreeNode(value={'same': 'same'}), tree.TreeNode(value={'same': 'same'})) self.assertNotEqual(tree.TreeNode(value={'same': 'same'}), tree.TreeNode(value={'same': 'other'}))
def test_empty(self): node = tree.TreeNode() self.assertEqual(node.name, '') self.assertEqual(node.value, {}) self.assertEqual(node.children, [])
def __init__(self, *args, **kwargs): super(Multiplex, self).__init__(*args, **kwargs) self._from_args_tree = tree.TreeNode()
def test_is_leaf(self): self.assertTrue(tree.TreeNode().is_leaf) self.assertTrue(tree.TreeNode(value={'foo': 'bar'}).is_leaf) self.assertFalse(tree.TreeNode(children=[tree.TreeNode()]).is_leaf)