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()
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)
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)
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)
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_subtrees(self): """ Subtrees should be ignored """ child = Tree(EXAMPLES + "child") assert child.find("/nobody") is None
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)
def test_find_root(self): """ Find metadata tree root """ tree = Tree(os.path.join(EXAMPLES, "wget", "protocols")) assert (tree.find("/download/test"))
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