Example #1
0
 def test_modify_after_adjust(self):
     """ Preserve original data even when adjust is used """
     item = '/requirements/protocols/ftp'
     wget = Tree(self.tempdir)
     # Expects new attribute + original data
     expected = {'new_attr': "new_value"}
     expected.update(wget.find(item).copy().get())
     wget.adjust(Context(arch='ppc64le'))
     with wget.find(item) as data:
         data['new_attr'] = "new_value"
     assert expected == Tree(self.tempdir).find(item).get()
Example #2
0
class TestTree(object):
    """ Tree class """
    def setup_method(self):
        """ Load examples """
        self.wget = Tree(WGET)
        self.merge = Tree(MERGE)

    def test_basic(self):
        """ No directory path given """
        with pytest.raises(FileError):
            Tree("")

    def test_hidden(self):
        """ Hidden files and directories """
        assert (".hidden" not in self.wget.children)

    def test_inheritance(self):
        """ Inheritance and data types """
        deep = self.wget.find('wget/recursion/deep')
        assert (deep.data['depth'] == 1000)
        assert (deep.data['description'] == 'Check recursive download options')
        assert (deep.data['tags'] == ['Tier2'])

    def test_merge(self):
        """ Attribute merging """
        child = self.merge.find('merge/parent/child')
        assert ('General' in child.data['description'])
        assert ('Specific' in child.data['description'])
        assert (child.data['tags'] == ['Tier1', 'Tier2'])
        assert (child.data['time'] == 15)
        assert ('time+' not in child.data)
        with pytest.raises(MergeError):
            child.update({"time+": "string"})

    def test_get(self):
        """ Get attributes """
        assert (isinstance(self.wget.get(), dict))
        assert ('Petr' in self.wget.get('tester'))

    def test_show(self):
        """ Show metadata """
        assert (isinstance(self.wget.show(brief=True), type("")))
        assert (isinstance(self.wget.show(), type("")))
        assert ('wget' in self.wget.show())

    def test_update(self):
        """ Update data """
        data = self.wget.get()
        self.wget.update(None)
        assert (self.wget.data == data)

    def test_find(self):
        """ Find node by name """
        assert (self.wget.find("non-existent") == None)
Example #3
0
 def test_inaccessible_directories(self):
     """ Inaccessible directories should be silently ignored """
     directory = tempfile.mkdtemp()
     accessible = os.path.join(directory, 'accessible')
     inaccessible = os.path.join(directory, 'inaccessible')
     os.mkdir(accessible, 511)
     os.mkdir(inaccessible, 000)
     with open(os.path.join(accessible, 'main.fmf'), 'w') as main:
         main.write('key: value\n')
     Tree.init(directory)
     tree = Tree(directory)
     assert tree.find('/accessible').get('key') == 'value'
     assert tree.find('/inaccessible') is None
     os.chmod(inaccessible, 511)
     rmtree(directory)
Example #4
0
class TestModify(unittest.TestCase):
    """ Verify storing modifed data to disk """
    def setUp(self):
        self.wget_path = EXAMPLES + "wget"
        self.tempdir = tempfile.mktemp()
        copytree(self.wget_path, self.tempdir)
        self.wget = Tree(self.tempdir)

    def tearDown(self):
        rmtree(self.tempdir)

    def test_inheritance(self):
        """ Inheritance and data types """
        item = self.wget.find('/recursion/deep')
        item_parent = self.wget.find('/recursion')
        # Modify data and store to disk
        with item as data:
            data.update(dict(depth=2000, new="two\nlines"))
        with item.parent as data:
            data.update(dict(parent_attr="value"))
        # Reload the data and verify
        self.wget = Tree(self.tempdir)
        item = self.wget.find('/recursion/deep')
        self.assertEqual(item.data['tags'], ['Tier2'])
        self.assertEqual(item.parent.data['tags'], ['Tier2'])
        self.assertEqual(item.data['depth'], 2000)
        self.assertIn('depth', item.data)
        self.assertNotIn('depth', item.parent.data)
        self.assertEqual(item.data['new'], "two\nlines")
        self.assertEqual(item.data['parent_attr'], "value")
        with open(os.path.join(self.tempdir, 'recursion/deep.fmf')) as file:
            self.assertTrue(re.search('two\n +lines', file.read()))

    def test_deep_modify(self):
        """ Deep structures """
        requirements = self.wget.find('/requirements')
        protocols = self.wget.find('/requirements/protocols')
        ftp = self.wget.find('/requirements/protocols/ftp')
        # Modify data and store to disk
        with requirements as data:
            data['new'] = 'some'
        with protocols as data:
            data.update(dict(coverage="changed", new_attr="val"))
        with ftp as data:
            data['server'] = 'vsftpd'
        # Reload the data and verify
        self.wget = Tree(self.tempdir)
        requirements = self.wget.find('/requirements')
        protocols = self.wget.find('/requirements/protocols')
        ftp = self.wget.find('/requirements/protocols/ftp')
        self.assertEqual(requirements.data["new"], "some")
        self.assertEqual(protocols.data["new"], "some")
        self.assertEqual(ftp.data["new"], "some")
        self.assertNotIn("server", protocols.data)
        self.assertIn("server", ftp.data)
        self.assertNotIn("new_attr", requirements.data)
        self.assertIn("new_attr", protocols.data)
        self.assertIn("new_attr", ftp.data)
        self.assertEqual(protocols.data["coverage"], "changed")
        self.assertIn('adjust', ftp.data)
        self.assertEqual(ftp.data['adjust'][0]['enabled'], False)
        self.assertEqual(ftp.data['adjust'][0]['when'], "arch != x86_64")

    def test_deep_hierarchy(self):
        """ Multiple virtual hierarchy levels shortcut """
        with open(os.path.join(self.tempdir, 'deep.fmf'), 'w') as file:
            file.write('/one/two/three:\n x: 1\n')
        deep = Tree(self.tempdir).find('/deep/one/two/three')
        with deep as data:
            data['y'] = 2
        deep = Tree(self.tempdir).find('/deep/one/two/three')
        self.assertEqual(deep.get('x'), 1)
        self.assertEqual(deep.get('y'), 2)

    def test_modify_empty(self):
        """ Nodes with no content should be handled as an empty dict """
        with self.wget.find('/download/requirements/spider') as data:
            data['x'] = 1
        self.wget = Tree(self.tempdir)
        node = self.wget.find('/download/requirements/spider')
        self.assertEqual(node.data['x'], 1)

    def test_modify_pop(self):
        """ Pop elements from node data """
        item = '/requirements/protocols/ftp'
        with self.wget.find(item) as data:
            data.pop('coverage')
            data.pop('tester+')
        self.wget = Tree(self.tempdir)
        node = self.wget.find(item)
        self.assertNotIn('coverage', node.data)
        self.assertIn('tester', node.data)
        self.assertIn('requirement', node.data)

    def test_modify_clear(self):
        """ Clear node data """
        item = '/requirements/protocols/ftp'
        with self.wget.find(item) as data:
            data.clear()
        self.wget = Tree(self.tempdir)
        node = self.wget.find(item)
        self.assertNotIn('coverage', node.data)
        self.assertIn('tester', node.data)
        self.assertNotIn('requirement', node.data)

    def test_modify_unsupported_method(self):
        """ Raise error for trees initialized from a dict """
        with pytest.raises(GeneralError, match='No raw data'):
            with Tree(dict(x=1)) as data:
                data['y'] = 2

    def test_context_manager(self):
        """
        try to use context manager for save node data
        """
        item = '/requirements/protocols/ftp'
        with self.wget.find(item) as data:
            data.pop("coverage")
            data.pop("tester+")
            data.update(dict(server="vsftpd"))
        self.wget = Tree(self.tempdir)
        node = self.wget.find(item)
        self.assertNotIn('coverage', node.data)
        self.assertIn('tester', node.data)
        self.assertIn('requirement', node.data)
        self.assertIn("server", node.data)
Example #5
0
 def test_empty(self):
     """ Empty structures should be ignored """
     child = Tree(EXAMPLES + "empty")
     assert child.find("/nothing") is None
     assert child.find("/zero") is None
Example #6
0
 def test_subtrees(self):
     """ Subtrees should be ignored """
     child = Tree(EXAMPLES + "child")
     assert child.find("/nobody") is None
Example #7
0
class TestTree(object):
    """ Tree class """
    def setup_method(self, method):
        """ Load examples """
        self.wget = Tree(EXAMPLES + "wget")
        self.merge = Tree(EXAMPLES + "merge")

    def test_basic(self):
        """ No directory path given """
        with pytest.raises(utils.GeneralError):
            Tree("")
        with pytest.raises(utils.GeneralError):
            Tree(None)
        with pytest.raises(utils.RootError):
            Tree("/")

    def test_hidden(self):
        """ Hidden files and directories """
        assert (".hidden" not in self.wget.children)

    def test_inheritance(self):
        """ Inheritance and data types """
        deep = self.wget.find('/recursion/deep')
        assert (deep.data['depth'] == 1000)
        assert (deep.data['description'] == 'Check recursive download options')
        assert (deep.data['tags'] == ['Tier2'])

    def test_scatter(self):
        """ Scattered files """
        scatter = Tree(EXAMPLES + "scatter").find("/object")
        assert (len(list(scatter.climb())) == 1)
        assert (scatter.data['one'] == 1)
        assert (scatter.data['two'] == 2)
        assert (scatter.data['three'] == 3)

    def test_scattered_inheritance(self):
        """ Inheritance of scattered files """
        grandson = Tree(EXAMPLES + "child").find("/son/grandson")
        assert (grandson.data['name'] == 'Hugo')
        assert (grandson.data['eyes'] == 'blue')
        assert (grandson.data['nose'] == 'long')
        assert (grandson.data['hair'] == 'fair')

    def test_subtrees(self):
        """ Subtrees should be ignored """
        child = Tree(EXAMPLES + "child")
        assert child.find("/nobody") is None

    def test_empty(self):
        """ Empty structures should be ignored """
        child = Tree(EXAMPLES + "empty")
        assert child.find("/nothing") is None
        assert child.find("/zero") is None

    def test_none_key(self):
        """ Handle None keys """
        with pytest.raises(utils.FormatError):
            tree = Tree({None: "weird key"})

    def test_deep_hierarchy(self):
        """ Deep hierarchy on one line """
        deep = Tree(EXAMPLES + "deep")
        assert len(deep.children) == 1

    def test_deep_dictionary(self):
        """ Get value from a deep dictionary """
        deep = Tree(EXAMPLES + "deep")
        assert deep.data['hardware']['memory']['size'] == 8
        assert deep.get(['hardware', 'memory', 'size']) == 8
        assert deep.get(['hardware', 'bad', 'size'], 12) == 12
        assert deep.get('nonexistent', default=3) == 3

    def test_merge_plus(self):
        """ Extending attributes using the '+' suffix """
        child = self.merge.find('/parent/extended')
        assert ('General' in child.data['description'])
        assert ('Specific' in child.data['description'])
        assert (child.data['tags'] == ['Tier1', 'Tier2', 'Tier3'])
        assert (child.data['time'] == 15)
        assert (child.data['vars'] == dict(x=1, y=2, z=3))
        assert (child.data['disabled'] == True)
        assert ('time+' not in child.data)
        with pytest.raises(utils.MergeError):
            child.data["time+"] = "string"
            child.inherit()

    def test_merge_minus(self):
        """ Reducing attributes using the '-' suffix """
        child = self.merge.find('/parent/reduced')
        assert ('General' in child.data['description'])
        assert ('description' not in child.data['description'])
        assert (child.data['tags'] == ['Tier1'])
        assert (child.data['time'] == 5)
        assert (child.data['vars'] == dict(x=1, y=2))
        assert ('time+' not in child.data)
        with pytest.raises(utils.MergeError):
            child.data["disabled-"] = True
            child.inherit()
        child.data.pop('disabled-')
        with pytest.raises(utils.MergeError):
            child.data["time-"] = "bad"
            child.inherit()

    def test_get(self):
        """ Get attributes """
        assert (isinstance(self.wget.get(), dict))
        assert ('Petr' in self.wget.get('tester'))

    def test_show(self):
        """ Show metadata """
        assert (isinstance(self.wget.show(brief=True), type("")))
        assert (self.wget.show(brief=True).endswith("\n"))
        assert (isinstance(self.wget.show(), type("")))
        assert (self.wget.show().endswith("\n"))
        assert ('tester' in self.wget.show())

    def test_update(self):
        """ Update data """
        data = self.wget.get()
        self.wget.update(None)
        assert (self.wget.data == data)

    def test_find_node(self):
        """ Find node by name """
        assert (self.wget.find("non-existent") == None)
        protocols = self.wget.find('/protocols')
        assert (isinstance(protocols, Tree))

    def test_find_root(self):
        """ Find metadata tree root """
        tree = Tree(os.path.join(EXAMPLES, "wget", "protocols"))
        assert (tree.find("/download/test"))

    def test_yaml_syntax_errors(self):
        """ Handle YAML syntax errors """
        path = tempfile.mkdtemp()
        fmf.cli.main("fmf init", path)
        with open(os.path.join(path, "main.fmf"), "w") as main:
            main.write("missing\ncolon:")
        with pytest.raises(utils.FileError):
            tree = fmf.Tree(path)
        rmtree(path)
Example #8
0
 def test_find_root(self):
     """ Find metadata tree root """
     tree = Tree(os.path.join(EXAMPLES, "wget", "protocols"))
     assert (tree.find("/download/test"))
Example #9
0
class TestTree(object):
    """ Tree class """
    def setup_method(self, method):
        """ Load examples """
        self.wget = Tree(EXAMPLES + "wget")
        self.merge = Tree(EXAMPLES + "merge")

    def test_basic(self):
        """ No directory path given """
        with pytest.raises(utils.GeneralError):
            Tree("")
        with pytest.raises(utils.GeneralError):
            Tree(None)
        with pytest.raises(utils.RootError):
            Tree("/")

    def test_hidden(self):
        """ Hidden files and directories """
        assert (".hidden" not in self.wget.children)

    def test_inheritance(self):
        """ Inheritance and data types """
        deep = self.wget.find('/recursion/deep')
        assert (deep.data['depth'] == 1000)
        assert (deep.data['description'] == 'Check recursive download options')
        assert (deep.data['tags'] == ['Tier2'])

    def test_scatter(self):
        """ Scattered files """
        scatter = Tree(EXAMPLES + "scatter").find("/object")
        assert (len(list(scatter.climb())) == 1)
        assert (scatter.data['one'] == 1)
        assert (scatter.data['two'] == 2)
        assert (scatter.data['three'] == 3)

    def test_scattered_inheritance(self):
        """ Inheritance of scattered files """
        grandson = Tree(EXAMPLES + "child").find("/son/grandson")
        assert (grandson.data['name'] == 'Hugo')
        assert (grandson.data['eyes'] == 'blue')
        assert (grandson.data['nose'] == 'long')
        assert (grandson.data['hair'] == 'fair')

    def test_subtrees(self):
        """ Subtrees should be ignored """
        child = Tree(EXAMPLES + "child")
        assert child.find("/nobody") is None

    def test_empty(self):
        """ Empty structures should be ignored """
        child = Tree(EXAMPLES + "empty")
        assert child.find("/nothing") is None
        assert child.find("/zero") is not None

    def test_none_key(self):
        """ Handle None keys """
        with pytest.raises(utils.FormatError):
            tree = Tree({None: "weird key"})

    def test_deep_hierarchy(self):
        """ Deep hierarchy on one line """
        deep = Tree(EXAMPLES + "deep")
        assert len(deep.children) == 1

    def test_deep_dictionary(self):
        """ Get value from a deep dictionary """
        deep = Tree(EXAMPLES + "deep")
        assert deep.data['hardware']['memory']['size'] == 8
        assert deep.get(['hardware', 'memory', 'size']) == 8
        assert deep.get(['hardware', 'bad', 'size'], 12) == 12
        assert deep.get('nonexistent', default=3) == 3

    def test_merge_plus(self):
        """ Extending attributes using the '+' suffix """
        child = self.merge.find('/parent/extended')
        assert ('General' in child.data['description'])
        assert ('Specific' in child.data['description'])
        assert (child.data['tags'] == ['Tier1', 'Tier2', 'Tier3'])
        assert (child.data['time'] == 15)
        assert (child.data['vars'] == dict(x=1, y=2, z=3))
        assert (child.data['disabled'] == True)
        assert ('time+' not in child.data)
        with pytest.raises(utils.MergeError):
            child.data["time+"] = "string"
            child.inherit()

    def test_merge_minus(self):
        """ Reducing attributes using the '-' suffix """
        child = self.merge.find('/parent/reduced')
        assert ('General' in child.data['description'])
        assert ('description' not in child.data['description'])
        assert (child.data['tags'] == ['Tier1'])
        assert (child.data['time'] == 5)
        assert (child.data['vars'] == dict(x=1))
        assert ('time+' not in child.data)
        with pytest.raises(utils.MergeError):
            child.data["disabled-"] = True
            child.inherit()
        child.data.pop('disabled-')
        with pytest.raises(utils.MergeError):
            child.data["time-"] = "bad"
            child.inherit()

    def test_merge_deep(self):
        """ Merging a deeply nested dictionary """
        child = self.merge.find('/parent/buried')
        assert (child.data['very']['deep']['dict'] == dict(x=2, y=1, z=0))

    def test_get(self):
        """ Get attributes """
        assert (isinstance(self.wget.get(), dict))
        assert ('Petr' in self.wget.get('tester'))

    def test_show(self):
        """ Show metadata """
        assert (isinstance(self.wget.show(brief=True), type("")))
        assert (self.wget.show(brief=True).endswith("\n"))
        assert (isinstance(self.wget.show(), type("")))
        assert (self.wget.show().endswith("\n"))
        assert ('tester' in self.wget.show())

    def test_update(self):
        """ Update data """
        data = self.wget.get()
        self.wget.update(None)
        assert (self.wget.data == data)

    def test_find_node(self):
        """ Find node by name """
        assert (self.wget.find("non-existent") == None)
        protocols = self.wget.find('/protocols')
        assert (isinstance(protocols, Tree))

    def test_find_root(self):
        """ Find metadata tree root """
        tree = Tree(os.path.join(EXAMPLES, "wget", "protocols"))
        assert (tree.find("/download/test"))

    def test_yaml_syntax_errors(self):
        """ Handle YAML syntax errors """
        path = tempfile.mkdtemp()
        fmf.cli.main("fmf init", path)
        with open(os.path.join(path, "main.fmf"), "w") as main:
            main.write("missing\ncolon:")
        with pytest.raises(utils.FileError):
            tree = fmf.Tree(path)
        rmtree(path)

    def test_yaml_duplicate_keys(self):
        """ Handle YAML duplicate keys """
        path = tempfile.mkdtemp()
        fmf.cli.main("fmf init", path)

        # Simple test
        with open(os.path.join(path, "main.fmf"), "w") as main:
            main.write("a: b\na: c\n")
        with pytest.raises(utils.FileError):
            fmf.Tree(path)

        # Add some hierarchy
        subdir = os.path.join(path, "dir")
        os.makedirs(subdir)
        with open(os.path.join(subdir, "a.fmf"), "w") as new_file:
            new_file.write("a: d\n")
        with pytest.raises(utils.FileError):
            fmf.Tree(path)

        # Remove duplicate key, check that inheritance doesn't
        # raise an exception
        with open(os.path.join(path, "main.fmf"), "w") as main:
            main.write("a: b\n")
        fmf.Tree(path)

        rmtree(path)

    def test_inaccessible_directories(self):
        """ Inaccessible directories should be silently ignored """
        directory = tempfile.mkdtemp()
        accessible = os.path.join(directory, 'accessible')
        inaccessible = os.path.join(directory, 'inaccessible')
        os.mkdir(accessible, 511)
        os.mkdir(inaccessible, 000)
        with open(os.path.join(accessible, 'main.fmf'), 'w') as main:
            main.write('key: value\n')
        Tree.init(directory)
        tree = Tree(directory)
        assert tree.find('/accessible').get('key') == 'value'
        assert tree.find('/inaccessible') is None
        os.chmod(inaccessible, 511)
        rmtree(directory)

    def test_node_copy_complete(self):
        """ Create deep copy of the whole tree """
        original = self.merge
        duplicate = original.copy()
        duplicate.data['x'] = 1
        assert original.parent is None
        assert duplicate.parent is None
        assert original.get('x') is None
        assert duplicate.get('x') == 1

    def test_node_copy_child(self):
        """ Duplicate child changes do not affect original """
        original = self.merge
        duplicate = original.copy()
        original_child = original.find('/parent/extended')
        duplicate_child = duplicate.find('/parent/extended')
        original_child.data['original'] = True
        duplicate_child.data['duplicate'] = True
        assert original_child.get('original') is True
        assert duplicate_child.get('original') is None
        assert original_child.get('duplicate') is None
        assert duplicate_child.get('duplicate') is True

    def test_node_copy_subtree(self):
        """ Create deep copy of a subtree """
        original = self.merge.find('/parent/extended')
        duplicate = original.copy()
        duplicate.data['x'] = 1
        assert original.parent == duplicate.parent
        assert duplicate.parent.name == '/parent'
        assert duplicate.get('x') == 1
        assert original.get('x') is None