From c9159b15f17be4d4f7262d1670e88398571a5b02 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Sun, 9 Oct 2011 07:41:53 +0200 Subject: [PATCH 01/21] use package, no need for another file Signed-off-by: Steven Armstrong --- lib/cdist/test/type/__init__.py | 146 +++++++++++++++++++++++++++++++ lib/cdist/test/type/test_type.py | 146 ------------------------------- 2 files changed, 146 insertions(+), 146 deletions(-) delete mode 100644 lib/cdist/test/type/test_type.py diff --git a/lib/cdist/test/type/__init__.py b/lib/cdist/test/type/__init__.py index e69de29b..5ba1f4b9 100644 --- a/lib/cdist/test/type/__init__.py +++ b/lib/cdist/test/type/__init__.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- +# +# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import os +import unittest + +import cdist.core + +import os.path as op +my_dir = op.abspath(op.dirname(__file__)) +fixtures = op.join(my_dir, 'fixtures') + + +class TypeTestCase(unittest.TestCase): + + def test_list_type_names(self): + base_path = op.join(fixtures, 'list_types') + type_names = cdist.core.Type.list_type_names(base_path) + self.assertEqual(type_names, ['__first', '__second', '__third']) + + def test_list_types(self): + base_path = op.join(fixtures, 'list_types') + types = list(cdist.core.Type.list_types(base_path)) + types_expected = [ + cdist.core.Type(base_path, '__first'), + cdist.core.Type(base_path, '__second'), + cdist.core.Type(base_path, '__third'), + ] + self.assertEqual(types, types_expected) + + def test_only_one_instance(self): + base_path = fixtures + cdist_type1 = cdist.core.Type(base_path, '__name_path') + cdist_type2 = cdist.core.Type(base_path, '__name_path') + self.assertEqual(id(cdist_type1), id(cdist_type2)) + + def test_name(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.name, '__name_path') + + def test_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.path, '__name_path') + + def test_absolute_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.absolute_path, os.path.join(base_path, '__name_path')) + + def test_manifest_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.manifest_path, os.path.join('__name_path', 'manifest')) + + def test_explorer_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.explorer_path, os.path.join('__name_path', 'explorer')) + + def test_gencode_local_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.gencode_local_path, os.path.join('__name_path', 'gencode-local')) + + def test_gencode_remote_path(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__name_path') + self.assertEqual(cdist_type.gencode_remote_path, os.path.join('__name_path', 'gencode-remote')) + + def test_singleton_is_singleton(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__singleton') + self.assertTrue(cdist_type.is_singleton) + + def test_not_singleton_is_singleton(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__not_singleton') + self.assertFalse(cdist_type.is_singleton) + + def test_install_is_install(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__install') + self.assertTrue(cdist_type.is_install) + + def test_not_install_is_install(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__not_install') + self.assertFalse(cdist_type.is_install) + + def test_with_explorers(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__with_explorers') + self.assertEqual(cdist_type.explorers, ['whatever']) + + def test_without_explorers(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__without_explorers') + self.assertEqual(cdist_type.explorers, []) + + def test_with_required_parameters(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__with_required_parameters') + self.assertEqual(cdist_type.required_parameters, ['required1', 'required2']) + + def test_without_required_parameters(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__without_required_parameters') + self.assertEqual(cdist_type.required_parameters, []) + + def test_with_optional_parameters(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__with_optional_parameters') + self.assertEqual(cdist_type.optional_parameters, ['optional1', 'optional2']) + + def test_without_optional_parameters(self): + base_path = fixtures + cdist_type = cdist.core.Type(base_path, '__without_optional_parameters') + self.assertEqual(cdist_type.optional_parameters, []) + +''' +suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) + +def suite(): + tests = [] + return unittest.TestSuite(map(ObjectTestCase, tests)) +''' diff --git a/lib/cdist/test/type/test_type.py b/lib/cdist/test/type/test_type.py deleted file mode 100644 index 5ba1f4b9..00000000 --- a/lib/cdist/test/type/test_type.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- coding: utf-8 -*- -# -# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# -# - -import os -import unittest - -import cdist.core - -import os.path as op -my_dir = op.abspath(op.dirname(__file__)) -fixtures = op.join(my_dir, 'fixtures') - - -class TypeTestCase(unittest.TestCase): - - def test_list_type_names(self): - base_path = op.join(fixtures, 'list_types') - type_names = cdist.core.Type.list_type_names(base_path) - self.assertEqual(type_names, ['__first', '__second', '__third']) - - def test_list_types(self): - base_path = op.join(fixtures, 'list_types') - types = list(cdist.core.Type.list_types(base_path)) - types_expected = [ - cdist.core.Type(base_path, '__first'), - cdist.core.Type(base_path, '__second'), - cdist.core.Type(base_path, '__third'), - ] - self.assertEqual(types, types_expected) - - def test_only_one_instance(self): - base_path = fixtures - cdist_type1 = cdist.core.Type(base_path, '__name_path') - cdist_type2 = cdist.core.Type(base_path, '__name_path') - self.assertEqual(id(cdist_type1), id(cdist_type2)) - - def test_name(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.name, '__name_path') - - def test_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.path, '__name_path') - - def test_absolute_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.absolute_path, os.path.join(base_path, '__name_path')) - - def test_manifest_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.manifest_path, os.path.join('__name_path', 'manifest')) - - def test_explorer_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.explorer_path, os.path.join('__name_path', 'explorer')) - - def test_gencode_local_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.gencode_local_path, os.path.join('__name_path', 'gencode-local')) - - def test_gencode_remote_path(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__name_path') - self.assertEqual(cdist_type.gencode_remote_path, os.path.join('__name_path', 'gencode-remote')) - - def test_singleton_is_singleton(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__singleton') - self.assertTrue(cdist_type.is_singleton) - - def test_not_singleton_is_singleton(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__not_singleton') - self.assertFalse(cdist_type.is_singleton) - - def test_install_is_install(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__install') - self.assertTrue(cdist_type.is_install) - - def test_not_install_is_install(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__not_install') - self.assertFalse(cdist_type.is_install) - - def test_with_explorers(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__with_explorers') - self.assertEqual(cdist_type.explorers, ['whatever']) - - def test_without_explorers(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__without_explorers') - self.assertEqual(cdist_type.explorers, []) - - def test_with_required_parameters(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__with_required_parameters') - self.assertEqual(cdist_type.required_parameters, ['required1', 'required2']) - - def test_without_required_parameters(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__without_required_parameters') - self.assertEqual(cdist_type.required_parameters, []) - - def test_with_optional_parameters(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__with_optional_parameters') - self.assertEqual(cdist_type.optional_parameters, ['optional1', 'optional2']) - - def test_without_optional_parameters(self): - base_path = fixtures - cdist_type = cdist.core.Type(base_path, '__without_optional_parameters') - self.assertEqual(cdist_type.optional_parameters, []) - -''' -suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) - -def suite(): - tests = [] - return unittest.TestSuite(map(ObjectTestCase, tests)) -''' From e27cd9e809d8d7c711662c6f9020f3e6c6ea9a15 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:23:27 +0200 Subject: [PATCH 02/21] when comparing objects, define equality as 'attributes are the same' Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 12d16838..b6bdeee3 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -80,6 +80,10 @@ class Object(object): def __repr__(self): return '' % self.name + def __eq__(self, other): + """define equality as 'attributes are the same'""" + return self.__dict__ == other.__dict__ + @property def explorer_path(self): # create absolute path From 7c12027311c4483de05bc0c583890382f7517536 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:30:28 +0200 Subject: [PATCH 03/21] test and fixtures for Object class/static methods Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 61 +++++++++++++++++++ .../test/object/fixtures/object/__first/.keep | 0 .../fixtures/object/__first/man/.cdist/.keep | 0 .../object/fixtures/object/__second/.keep | 0 .../object/__second/on-the/.cdist/.keep | 0 .../test/object/fixtures/object/__third/.keep | 0 .../fixtures/object/__third/moon/.cdist/.keep | 0 .../test/object/fixtures/type/__first/.keep | 0 .../test/object/fixtures/type/__second/.keep | 0 .../test/object/fixtures/type/__third/.keep | 0 lib/cdist/test/test_object.py | 46 -------------- 11 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 lib/cdist/test/object/__init__.py create mode 100644 lib/cdist/test/object/fixtures/object/__first/.keep create mode 100644 lib/cdist/test/object/fixtures/object/__first/man/.cdist/.keep create mode 100644 lib/cdist/test/object/fixtures/object/__second/.keep create mode 100644 lib/cdist/test/object/fixtures/object/__second/on-the/.cdist/.keep create mode 100644 lib/cdist/test/object/fixtures/object/__third/.keep create mode 100644 lib/cdist/test/object/fixtures/object/__third/moon/.cdist/.keep create mode 100644 lib/cdist/test/object/fixtures/type/__first/.keep create mode 100644 lib/cdist/test/object/fixtures/type/__second/.keep create mode 100644 lib/cdist/test/object/fixtures/type/__third/.keep delete mode 100644 lib/cdist/test/test_object.py diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py new file mode 100644 index 00000000..3d04a7a3 --- /dev/null +++ b/lib/cdist/test/object/__init__.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# +# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import os +import tempfile +import unittest +import shutil + +import cdist.core + +import os.path as op +my_dir = op.abspath(op.dirname(__file__)) +fixtures = op.join(my_dir, 'fixtures') +object_base_path = op.join(fixtures, 'object') +type_base_path = op.join(fixtures, 'type') + +class ObjectClassTestCase(unittest.TestCase): + + def test_list_object_names(self): + object_names = list(cdist.core.Object.list_object_names(object_base_path)) + self.assertEqual(object_names, ['__first/man', '__second/on-the', '__third/moon']) + + def test_list_type_names(self): + type_names = list(cdist.core.Object.list_type_names(object_base_path)) + self.assertEqual(type_names, ['__first', '__second', '__third']) + + def test_list_objects(self): + objects = list(cdist.core.Object.list_objects(object_base_path, type_base_path)) + objects_expected = [ + cdist.core.Object(cdist.core.Type(type_base_path, '__first'), object_base_path, 'man'), + cdist.core.Object(cdist.core.Type(type_base_path, '__second'), object_base_path, 'on-the'), + cdist.core.Object(cdist.core.Type(type_base_path, '__third'), object_base_path, 'moon'), + ] + self.assertEqual(objects, objects_expected) + + +''' +suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) + +def suite(): + tests = [] + return unittest.TestSuite(map(ObjectTestCase, tests)) +''' diff --git a/lib/cdist/test/object/fixtures/object/__first/.keep b/lib/cdist/test/object/fixtures/object/__first/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/object/__first/man/.cdist/.keep b/lib/cdist/test/object/fixtures/object/__first/man/.cdist/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/object/__second/.keep b/lib/cdist/test/object/fixtures/object/__second/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/object/__second/on-the/.cdist/.keep b/lib/cdist/test/object/fixtures/object/__second/on-the/.cdist/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/object/__third/.keep b/lib/cdist/test/object/fixtures/object/__third/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/.keep b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/type/__first/.keep b/lib/cdist/test/object/fixtures/type/__first/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/type/__second/.keep b/lib/cdist/test/object/fixtures/type/__second/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/object/fixtures/type/__third/.keep b/lib/cdist/test/object/fixtures/type/__third/.keep new file mode 100644 index 00000000..e69de29b diff --git a/lib/cdist/test/test_object.py b/lib/cdist/test/test_object.py deleted file mode 100644 index ae584840..00000000 --- a/lib/cdist/test/test_object.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# -# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# -# - -import os -import tempfile -import unittest -import shutil - -import os.path as op -my_dir = op.abspath(op.dirname(__file__)) -base_path = op.join(my_dir, 'fixtures') - -class ObjectTestCase(unittest.TestCase): - def setUp(self): - # FIXME: use defined set of types for testing? - # FIXME: generate object tree or use predefined? - self.object_base_dir = tempfile.mkdtemp() - - def tearDown(self): - shutil.rmtree(self.temp_dir) - -''' -suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) - -def suite(): - tests = [] - return unittest.TestSuite(map(ObjectTestCase, tests)) -''' From f3b942e591423c09e71e92af32887d6782f3d5ee Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:34:16 +0200 Subject: [PATCH 04/21] test for Object paths Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 3d04a7a3..c1685c58 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -52,10 +52,28 @@ class ObjectClassTestCase(unittest.TestCase): self.assertEqual(objects, objects_expected) -''' -suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) +class ObjectTestCase(unittest.TestCase): -def suite(): - tests = [] - return unittest.TestSuite(map(ObjectTestCase, tests)) -''' + def setUp(self): + self.cdist_type = cdist.core.Type(type_base_path, '__third') + self.cdist_object = cdist.core.Object(self.cdist_type, object_base_path, 'moon') + + def test_name(self): + self.assertEqual(self.cdist_object.name, '__third/moon') + + def test_path(self): + self.assertEqual(self.cdist_object.path, '__third/moon/.cdist') + + def test_absolute_path(self): + self.assertEqual(self.cdist_object.absolute_path, os.path.join(object_base_path, '__third/moon/.cdist')) + + def test_code_local_path(self): + self.assertEqual(self.cdist_object.code_local_path, '__third/moon/.cdist/code-local') + + def test_code_remote_path(self): + self.assertEqual(self.cdist_object.code_remote_path, '__third/moon/.cdist/code-remote') + + def test_parameter_path(self): + self.assertEqual(self.cdist_object.parameter_path, '__third/moon/.cdist/parameter') + +#suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) From 8384176080156f3fb6b3087eb5e26b177827c963 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:36:48 +0200 Subject: [PATCH 05/21] test Object explorer_path Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 3 +++ .../object/fixtures/object/__third/moon/.cdist/explorer/.keep | 0 2 files changed, 3 insertions(+) create mode 100644 lib/cdist/test/object/fixtures/object/__third/moon/.cdist/explorer/.keep diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index c1685c58..55af5bf9 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -76,4 +76,7 @@ class ObjectTestCase(unittest.TestCase): def test_parameter_path(self): self.assertEqual(self.cdist_object.parameter_path, '__third/moon/.cdist/parameter') + def test_explorer_path(self): + self.assertEqual(self.cdist_object.explorer_path, '__third/moon/.cdist/explorer') + #suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) diff --git a/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/explorer/.keep b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/explorer/.keep new file mode 100644 index 00000000..e69de29b From 88a1e34f3004defd6020f753c9ecec9669302d96 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:44:29 +0200 Subject: [PATCH 06/21] test for Object object_id Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 55af5bf9..cd6e7f04 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -61,6 +61,9 @@ class ObjectTestCase(unittest.TestCase): def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon') + def test_object_id(self): + self.assertEqual(self.cdist_object.object_id, 'moon') + def test_path(self): self.assertEqual(self.cdist_object.path, '__third/moon/.cdist') From abf318ae90b827b2fc99555b386c8321a38e0cc0 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:47:06 +0200 Subject: [PATCH 07/21] test and fixtures for Object parameters Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 4 ++++ .../object/fixtures/object/__third/moon/.cdist/parameter/name | 1 + .../fixtures/object/__third/moon/.cdist/parameter/planet | 1 + 3 files changed, 6 insertions(+) create mode 100644 lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/name create mode 100644 lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/planet diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index cd6e7f04..a9edfdd0 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -82,4 +82,8 @@ class ObjectTestCase(unittest.TestCase): def test_explorer_path(self): self.assertEqual(self.cdist_object.explorer_path, '__third/moon/.cdist/explorer') + def test_parameters(self): + expected_parameters = {'planet': 'Saturn', 'name': 'Prometheus'} + self.assertEqual(self.cdist_object.parameters, expected_parameters) + #suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) diff --git a/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/name b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/name new file mode 100644 index 00000000..4129a761 --- /dev/null +++ b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/name @@ -0,0 +1 @@ +Prometheus diff --git a/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/planet b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/planet new file mode 100644 index 00000000..8e6ee422 --- /dev/null +++ b/lib/cdist/test/object/fixtures/object/__third/moon/.cdist/parameter/planet @@ -0,0 +1 @@ +Saturn From 96ca5b6988f249b8320c977d3242846b2e1f0519 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:48:19 +0200 Subject: [PATCH 08/21] bugfix: use absolute path to when accessing file sytem (unittest discoverd :-) Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index b6bdeee3..96c6076a 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -114,7 +114,7 @@ class Object(object): @property def parameters(self): if not self.__parameters: - self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.path, "parameter")) + self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.absolute_path, "parameter")) return self.__parameters @parameters.setter @@ -122,7 +122,7 @@ class Object(object): if isinstance(value, cdist.core.property.DirectoryDict): self.__parameters = value else: - self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.path, "parameter"), value) + self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.absolute_path, "parameter"), value) ### /parameters From 0ba6d551919090d079ef6667e1f228be0b79c358 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 09:57:56 +0200 Subject: [PATCH 09/21] raise exception when given a relative path Signed-off-by: Steven Armstrong --- lib/cdist/core/property.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/cdist/core/property.py b/lib/cdist/core/property.py index 30887547..e63cadcf 100644 --- a/lib/cdist/core/property.py +++ b/lib/cdist/core/property.py @@ -25,11 +25,21 @@ import collections import cdist +class AbsolutePathRequiredError(cdist.Error): + def __init__(self, path): + self.path = path + + def __str__(self): + return 'Absolute path required, got: %s' % self.path + + class FileList(collections.MutableSequence): """A list that stores it's state in a file. """ def __init__(self, path, initial=None): + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) self._path = path if initial: # delete existing file @@ -108,6 +118,8 @@ class DirectoryDict(collections.MutableMapping): """ def __init__(self, path, dict=None, **kwargs): + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) self._path = path if dict is not None: self.update(dict) From b1efc27b39b02ae43cd43156ad82e8a61022023c Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 10:00:42 +0200 Subject: [PATCH 10/21] test for Object requirements Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index a9edfdd0..910a75e1 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -86,4 +86,8 @@ class ObjectTestCase(unittest.TestCase): expected_parameters = {'planet': 'Saturn', 'name': 'Prometheus'} self.assertEqual(self.cdist_object.parameters, expected_parameters) + def test_requirements(self): + expected = [] + self.assertEqual(list(self.cdist_object.requirements), expected) + #suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) From 86f976976ec5743fa1dfee2dcc5b67f11a3b1066 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 10:01:28 +0200 Subject: [PATCH 11/21] bugfix: use absolute path when accessing file system Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 96c6076a..76e8faa1 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -98,7 +98,7 @@ class Object(object): @property def requirements(self): if not self.__requirements: - self.__requirements = cdist.core.property.FileList(os.path.join(self.path, "require")) + self.__requirements = cdist.core.property.FileList(os.path.join(self.absolute_path, "require")) return self.__requirements @requirements.setter @@ -106,7 +106,7 @@ class Object(object): if isinstance(value, cdist.core.property.FileList): self.__requirements = value else: - self.__requirements = cdist.core.property.FileList(os.path.join(self.path, "require"), value) + self.__requirements = cdist.core.property.FileList(os.path.join(self.absolute_path, "require"), value) ### /requirements From f2701cb5124d513b9c80fb45ef3ab527ade4a9e5 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 10:04:36 +0200 Subject: [PATCH 12/21] test for Object changed Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index 910a75e1..a85e8df9 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -58,6 +58,9 @@ class ObjectTestCase(unittest.TestCase): self.cdist_type = cdist.core.Type(type_base_path, '__third') self.cdist_object = cdist.core.Object(self.cdist_type, object_base_path, 'moon') + def tearDown(self): + self.cdist_object.changed = False + def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon') @@ -90,4 +93,11 @@ class ObjectTestCase(unittest.TestCase): expected = [] self.assertEqual(list(self.cdist_object.requirements), expected) + def test_changed(self): + self.assertFalse(self.cdist_object.changed) + + def test_changed_after_changing(self): + self.cdist_object.changed = True + self.assertTrue(self.cdist_object.changed) + #suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) From 7855a485b627100886275e9446e2257b4c12f054 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 10:05:46 +0200 Subject: [PATCH 13/21] test for Object prepared Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index a85e8df9..c490bdc3 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -60,6 +60,7 @@ class ObjectTestCase(unittest.TestCase): def tearDown(self): self.cdist_object.changed = False + self.cdist_object.prepared = False def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon') @@ -100,4 +101,10 @@ class ObjectTestCase(unittest.TestCase): self.cdist_object.changed = True self.assertTrue(self.cdist_object.changed) + def test_prepared(self): + self.assertFalse(self.cdist_object.prepared) + + def test_prepared_after_changing(self): + self.cdist_object.prepared = True + self.assertTrue(self.cdist_object.prepared) #suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) From 6de7bd3377d060d108df07fcabe1506d66666232 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 10:06:41 +0200 Subject: [PATCH 14/21] test for Object ran Signed-off-by: Steven Armstrong --- lib/cdist/test/object/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/cdist/test/object/__init__.py b/lib/cdist/test/object/__init__.py index c490bdc3..75322654 100644 --- a/lib/cdist/test/object/__init__.py +++ b/lib/cdist/test/object/__init__.py @@ -61,6 +61,7 @@ class ObjectTestCase(unittest.TestCase): def tearDown(self): self.cdist_object.changed = False self.cdist_object.prepared = False + self.cdist_object.ran = False def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon') @@ -107,4 +108,10 @@ class ObjectTestCase(unittest.TestCase): def test_prepared_after_changing(self): self.cdist_object.prepared = True self.assertTrue(self.cdist_object.prepared) -#suite = unittest.TestLoader().loadTestsFromTestCase(ObjectTestCase) + + def test_ran(self): + self.assertFalse(self.cdist_object.ran) + + def test_ran_after_changing(self): + self.cdist_object.ran = True + self.assertTrue(self.cdist_object.ran) From 44a722042a4e321c38ac50b0b796a4fa494f09e4 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 14:37:33 +0200 Subject: [PATCH 15/21] new class for using filesystem as backend for boolean properties Signed-off-by: Steven Armstrong --- lib/cdist/core/property.py | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/lib/cdist/core/property.py b/lib/cdist/core/property.py index e63cadcf..11dddcf3 100644 --- a/lib/cdist/core/property.py +++ b/lib/cdist/core/property.py @@ -165,3 +165,50 @@ class DirectoryDictProperty(DirectoryDict): def __delete__(self, obj): raise AttributeError("can't delete attribute") + + +class FileBooleanProperty(object): + def __init__(self, path): + """ + :param path: string or callable + + Usage: + + class Foo(object): + changed = FileBoolean(lambda obj: os.path.join(obj.absolute_path, 'changed')) + other_boolean = FileBoolean('/tmp/other_boolean') + + def __init__(self): + self.absolute_path = '/tmp/foo_boolean' + + """ + self._path = path + + def _get_path(self, *args, **kwargs): + path = self._path + if callable(path): + return path(*args, **kwargs) + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + return path + + # Descriptor Protocol + def __get__(self, obj, objtype=None): + if obj is None: + return self.__class__ + path = self._get_path(obj) + return os.path.isfile(path) + + def __set__(self, obj, value): + path = self._get_path(obj) + if value: + open(path, "w").close() + else: + try: + os.remove(path) + except EnvironmentError: + # ignore + pass + + def __delete__(self, obj): + raise AttributeError("can't delete attribute") From f3932bb662bb73c970ba59b74aaba9bde182237d Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 14:54:26 +0200 Subject: [PATCH 16/21] move file based properties out of core Signed-off-by: Steven Armstrong --- lib/cdist/util/property.py | 214 +++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 lib/cdist/util/property.py diff --git a/lib/cdist/util/property.py b/lib/cdist/util/property.py new file mode 100644 index 00000000..11dddcf3 --- /dev/null +++ b/lib/cdist/util/property.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# +# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# +# + +import os +import collections + +import cdist + + +class AbsolutePathRequiredError(cdist.Error): + def __init__(self, path): + self.path = path + + def __str__(self): + return 'Absolute path required, got: %s' % self.path + + +class FileList(collections.MutableSequence): + """A list that stores it's state in a file. + + """ + def __init__(self, path, initial=None): + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + self._path = path + if initial: + # delete existing file + os.unlink(self._path) + for i in initial: + self.append(i) + + def __read(self): + lines = [] + try: + with open(self._path) as fd: + for line in fd: + lines.append(line.rstrip('\n')) + except EnvironmentError as e: + # error ignored + pass + return lines + + def __write(self, lines): + try: + with open(self._path, 'w') as fd: + for line in lines: + fd.write(str(line) + '\n') + except EnvironmentError as e: + # error ignored + raise + + def __repr__(self): + return repr(list(self)) + + def __getitem__(self, index): + return self.__read()[index] + + def __setitem__(self, index, value): + lines = self.__read() + lines[index] = value + self.__write(lines) + + def __delitem__(self, index): + lines = self.__read() + del lines[index] + self.__write(lines) + + def __len__(self): + lines = self.__read() + return len(lines) + + def insert(self, index, value): + lines = self.__read() + lines.insert(index, value) + self.__write(lines) + + def sort(self): + lines = sorted(self) + self.__write(lines) + + +class FileListProperty(FileList): + # Descriptor Protocol + def __get__(self, obj, objtype=None): + if obj is None: + return self.__class__ + return self + + def __set__(self, obj, value): + os.unlink(self._path) + for item in value: + self.append(item) + + def __delete__(self, obj): + raise AttributeError("can't delete attribute") + + +class DirectoryDict(collections.MutableMapping): + """A dict that stores it's state in a directory. + + """ + def __init__(self, path, dict=None, **kwargs): + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + self._path = path + if dict is not None: + self.update(dict) + if len(kwargs): + self.update(kwargs) + + def __repr__(self): + return repr(dict(self)) + + def __getitem__(self, key): + try: + with open(os.path.join(self._path, key), "r") as fd: + return fd.read().rstrip('\n') + except EnvironmentError: + raise KeyError(key) + + def __setitem__(self, key, value): + with open(os.path.join(self._path, key), "w") as fd: + fd.write(str(value)) + + def __delitem__(self, key): + os.remove(os.path.join(self._path, key)) + + def __iter__(self): + return iter(os.listdir(self._path)) + + def __len__(self): + return len(os.listdir(self._path)) + + +class DirectoryDictProperty(DirectoryDict): + # Descriptor Protocol + def __get__(self, obj, objtype=None): + if obj is None: + return self.__class__ + return self + + def __set__(self, obj, value): + for name in self.keys(): + del self[name] + if value is not None: + self.update(value) + + def __delete__(self, obj): + raise AttributeError("can't delete attribute") + + +class FileBooleanProperty(object): + def __init__(self, path): + """ + :param path: string or callable + + Usage: + + class Foo(object): + changed = FileBoolean(lambda obj: os.path.join(obj.absolute_path, 'changed')) + other_boolean = FileBoolean('/tmp/other_boolean') + + def __init__(self): + self.absolute_path = '/tmp/foo_boolean' + + """ + self._path = path + + def _get_path(self, *args, **kwargs): + path = self._path + if callable(path): + return path(*args, **kwargs) + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + return path + + # Descriptor Protocol + def __get__(self, obj, objtype=None): + if obj is None: + return self.__class__ + path = self._get_path(obj) + return os.path.isfile(path) + + def __set__(self, obj, value): + path = self._get_path(obj) + if value: + open(path, "w").close() + else: + try: + os.remove(path) + except EnvironmentError: + # ignore + pass + + def __delete__(self, obj): + raise AttributeError("can't delete attribute") From 4a3bc7284664c82b03f433ce100f02a1a932833d Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 14:54:35 +0200 Subject: [PATCH 17/21] move file based properties out of core Signed-off-by: Steven Armstrong --- lib/cdist/core/property.py | 214 ------------------------------------- 1 file changed, 214 deletions(-) delete mode 100644 lib/cdist/core/property.py diff --git a/lib/cdist/core/property.py b/lib/cdist/core/property.py deleted file mode 100644 index 11dddcf3..00000000 --- a/lib/cdist/core/property.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- -# -# 2010-2011 Steven Armstrong (steven-cdist at armstrong.cc) -# -# This file is part of cdist. -# -# cdist is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# -# - -import os -import collections - -import cdist - - -class AbsolutePathRequiredError(cdist.Error): - def __init__(self, path): - self.path = path - - def __str__(self): - return 'Absolute path required, got: %s' % self.path - - -class FileList(collections.MutableSequence): - """A list that stores it's state in a file. - - """ - def __init__(self, path, initial=None): - if not os.path.isabs(path): - raise AbsolutePathRequiredError(path) - self._path = path - if initial: - # delete existing file - os.unlink(self._path) - for i in initial: - self.append(i) - - def __read(self): - lines = [] - try: - with open(self._path) as fd: - for line in fd: - lines.append(line.rstrip('\n')) - except EnvironmentError as e: - # error ignored - pass - return lines - - def __write(self, lines): - try: - with open(self._path, 'w') as fd: - for line in lines: - fd.write(str(line) + '\n') - except EnvironmentError as e: - # error ignored - raise - - def __repr__(self): - return repr(list(self)) - - def __getitem__(self, index): - return self.__read()[index] - - def __setitem__(self, index, value): - lines = self.__read() - lines[index] = value - self.__write(lines) - - def __delitem__(self, index): - lines = self.__read() - del lines[index] - self.__write(lines) - - def __len__(self): - lines = self.__read() - return len(lines) - - def insert(self, index, value): - lines = self.__read() - lines.insert(index, value) - self.__write(lines) - - def sort(self): - lines = sorted(self) - self.__write(lines) - - -class FileListProperty(FileList): - # Descriptor Protocol - def __get__(self, obj, objtype=None): - if obj is None: - return self.__class__ - return self - - def __set__(self, obj, value): - os.unlink(self._path) - for item in value: - self.append(item) - - def __delete__(self, obj): - raise AttributeError("can't delete attribute") - - -class DirectoryDict(collections.MutableMapping): - """A dict that stores it's state in a directory. - - """ - def __init__(self, path, dict=None, **kwargs): - if not os.path.isabs(path): - raise AbsolutePathRequiredError(path) - self._path = path - if dict is not None: - self.update(dict) - if len(kwargs): - self.update(kwargs) - - def __repr__(self): - return repr(dict(self)) - - def __getitem__(self, key): - try: - with open(os.path.join(self._path, key), "r") as fd: - return fd.read().rstrip('\n') - except EnvironmentError: - raise KeyError(key) - - def __setitem__(self, key, value): - with open(os.path.join(self._path, key), "w") as fd: - fd.write(str(value)) - - def __delitem__(self, key): - os.remove(os.path.join(self._path, key)) - - def __iter__(self): - return iter(os.listdir(self._path)) - - def __len__(self): - return len(os.listdir(self._path)) - - -class DirectoryDictProperty(DirectoryDict): - # Descriptor Protocol - def __get__(self, obj, objtype=None): - if obj is None: - return self.__class__ - return self - - def __set__(self, obj, value): - for name in self.keys(): - del self[name] - if value is not None: - self.update(value) - - def __delete__(self, obj): - raise AttributeError("can't delete attribute") - - -class FileBooleanProperty(object): - def __init__(self, path): - """ - :param path: string or callable - - Usage: - - class Foo(object): - changed = FileBoolean(lambda obj: os.path.join(obj.absolute_path, 'changed')) - other_boolean = FileBoolean('/tmp/other_boolean') - - def __init__(self): - self.absolute_path = '/tmp/foo_boolean' - - """ - self._path = path - - def _get_path(self, *args, **kwargs): - path = self._path - if callable(path): - return path(*args, **kwargs) - if not os.path.isabs(path): - raise AbsolutePathRequiredError(path) - return path - - # Descriptor Protocol - def __get__(self, obj, objtype=None): - if obj is None: - return self.__class__ - path = self._get_path(obj) - return os.path.isfile(path) - - def __set__(self, obj, value): - path = self._get_path(obj) - if value: - open(path, "w").close() - else: - try: - os.remove(path) - except EnvironmentError: - # ignore - pass - - def __delete__(self, obj): - raise AttributeError("can't delete attribute") From 09632373216f1f29a11e4743954044c90e82df4b Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 14:54:50 +0200 Subject: [PATCH 18/21] new package cdist.util Signed-off-by: Steven Armstrong --- lib/cdist/util/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/cdist/util/__init__.py diff --git a/lib/cdist/util/__init__.py b/lib/cdist/util/__init__.py new file mode 100644 index 00000000..e69de29b From 915ec6d9adee3fd10eaa035075298d4dda1662e5 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 16:37:56 +0200 Subject: [PATCH 19/21] rename property module to fsproperty Signed-off-by: Steven Armstrong --- lib/cdist/util/{property.py => fsproperty.py} | 92 +++++++++++++++---- 1 file changed, 75 insertions(+), 17 deletions(-) rename lib/cdist/util/{property.py => fsproperty.py} (69%) diff --git a/lib/cdist/util/property.py b/lib/cdist/util/fsproperty.py similarity index 69% rename from lib/cdist/util/property.py rename to lib/cdist/util/fsproperty.py index 11dddcf3..1af2f0f5 100644 --- a/lib/cdist/util/property.py +++ b/lib/cdist/util/fsproperty.py @@ -40,17 +40,17 @@ class FileList(collections.MutableSequence): def __init__(self, path, initial=None): if not os.path.isabs(path): raise AbsolutePathRequiredError(path) - self._path = path + self.path = path if initial: # delete existing file - os.unlink(self._path) + os.unlink(self.path) for i in initial: self.append(i) def __read(self): lines = [] try: - with open(self._path) as fd: + with open(self.path) as fd: for line in fd: lines.append(line.rstrip('\n')) except EnvironmentError as e: @@ -60,7 +60,7 @@ class FileList(collections.MutableSequence): def __write(self, lines): try: - with open(self._path, 'w') as fd: + with open(self.path, 'w') as fd: for line in lines: fd.write(str(line) + '\n') except EnvironmentError as e: @@ -98,14 +98,43 @@ class FileList(collections.MutableSequence): class FileListProperty(FileList): + + def __init__(self, path): + """ + :param path: string or callable + + Usage: + + class Foo(object): + parameters = DirectoryDictProperty(lambda obj: os.path.join(obj.absolute_path, 'parameter')) + other_dict = DirectoryDictProperty('/tmp/folder') + + def __init__(self): + self.absolute_path = '/tmp/foo' + + """ + self.path = None + self.__path = path + + def _set_path(self, *args, **kwargs): + if self.path is None: + path = self.__path + if callable(path): + path = path(*args, **kwargs) + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + self.path = path + # Descriptor Protocol def __get__(self, obj, objtype=None): if obj is None: return self.__class__ + self._set_path(obj) return self def __set__(self, obj, value): - os.unlink(self._path) + self._set_path(obj) + os.unlink(self.path) for item in value: self.append(item) @@ -117,13 +146,13 @@ class DirectoryDict(collections.MutableMapping): """A dict that stores it's state in a directory. """ - def __init__(self, path, dict=None, **kwargs): + def __init__(self, path, initial=None, **kwargs): if not os.path.isabs(path): raise AbsolutePathRequiredError(path) - self._path = path - if dict is not None: - self.update(dict) - if len(kwargs): + self.path = path + if initial is not None: + self.update(initial) + if kwargs: self.update(kwargs) def __repr__(self): @@ -131,36 +160,65 @@ class DirectoryDict(collections.MutableMapping): def __getitem__(self, key): try: - with open(os.path.join(self._path, key), "r") as fd: + with open(os.path.join(self.path, key), "r") as fd: return fd.read().rstrip('\n') except EnvironmentError: raise KeyError(key) def __setitem__(self, key, value): - with open(os.path.join(self._path, key), "w") as fd: + with open(os.path.join(self.path, key), "w") as fd: fd.write(str(value)) def __delitem__(self, key): - os.remove(os.path.join(self._path, key)) + os.remove(os.path.join(self.path, key)) def __iter__(self): - return iter(os.listdir(self._path)) + return iter(os.listdir(self.path)) def __len__(self): - return len(os.listdir(self._path)) + return len(os.listdir(self.path)) class DirectoryDictProperty(DirectoryDict): + + def __init__(self, path): + """ + :param path: string or callable + + Usage: + + class Foo(object): + parameters = DirectoryDictProperty(lambda obj: os.path.join(obj.absolute_path, 'parameter')) + other_dict = DirectoryDictProperty('/tmp/folder') + + def __init__(self): + self.absolute_path = '/tmp/foo' + + """ + self.path = None + self.__path = path + + def _set_path(self, *args, **kwargs): + if self.path is None: + path = self.__path + if callable(path): + path = path(*args, **kwargs) + if not os.path.isabs(path): + raise AbsolutePathRequiredError(path) + self.path = path + # Descriptor Protocol def __get__(self, obj, objtype=None): if obj is None: return self.__class__ + self._set_path(obj) return self def __set__(self, obj, value): - for name in self.keys(): - del self[name] + self._set_path(obj) if value is not None: + for name in self.keys(): + del self[name] self.update(value) def __delete__(self, obj): From bbcecc03ef035f6b0c18ca59720c0a9b423dc258 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 16:39:48 +0200 Subject: [PATCH 20/21] remove redundant code, use new fsproperty module instead Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 105 +++------------------------------------ 1 file changed, 8 insertions(+), 97 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 76e8faa1..2ae5f81b 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -25,14 +25,14 @@ import os import collections import cdist -import cdist.core.property +import cdist.core +from cdist.util import fsproperty log = logging.getLogger(__name__) DOT_CDIST = '.cdist' -# FIXME: i should not have to care about prefix directory, local, remote and such. -# I know what my internals look like, the outside is none of my business. + class Object(object): """Represents a cdist object. @@ -93,97 +93,8 @@ class Object(object): # return relative path return os.path.join(self.path, "explorer") - - ### requirements - @property - def requirements(self): - if not self.__requirements: - self.__requirements = cdist.core.property.FileList(os.path.join(self.absolute_path, "require")) - return self.__requirements - - @requirements.setter - def requirements(self, value): - if isinstance(value, cdist.core.property.FileList): - self.__requirements = value - else: - self.__requirements = cdist.core.property.FileList(os.path.join(self.absolute_path, "require"), value) - ### /requirements - - - ### parameters - @property - def parameters(self): - if not self.__parameters: - self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.absolute_path, "parameter")) - return self.__parameters - - @parameters.setter - def parameters(self, value): - if isinstance(value, cdist.core.property.DirectoryDict): - self.__parameters = value - else: - self.__parameters = cdist.core.property.DirectoryDict(os.path.join(self.absolute_path, "parameter"), value) - ### /parameters - - - ### changed - @property - def changed(self): - """Check whether the object has been changed.""" - return os.path.isfile(os.path.join(self.absolute_path, "changed")) - - @changed.setter - def changed(self, value): - """Change the objects changed status.""" - path = os.path.join(self.absolute_path, "changed") - if value: - open(path, "w").close() - else: - try: - os.remove(path) - except EnvironmentError: - # ignore - pass - ### /changed - - - ### prepared - @property - def prepared(self): - """Check whether the object has been prepared.""" - return os.path.isfile(os.path.join(self.absolute_path, "prepared")) - - @prepared.setter - def prepared(self, value): - """Change the objects prepared status.""" - path = os.path.join(self.absolute_path, "prepared") - if value: - open(path, "w").close() - else: - try: - os.remove(path) - except EnvironmentError: - # ignore - pass - ### /prepared - - - ### ran - @property - def ran(self): - """Check whether the object has been ran.""" - return os.path.isfile(os.path.join(self.absolute_path, "ran")) - - @ran.setter - def ran(self, value): - """Change the objects ran status.""" - path = os.path.join(self.absolute_path, "ran") - if value: - open(path, "w").close() - else: - try: - os.remove(path) - except EnvironmentError: - # ignore - pass - ### /ran + requirements = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'require')) + parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.absolute_path, 'parameter')) + changed = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "changed")) + prepared = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "prepared")) + ran = fsproperty.FileBooleanProperty(lambda obj: os.path.join(obj.absolute_path, "ran")) From af8f006fc682d120924e44ef024a7eee09304f74 Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 10 Oct 2011 16:50:56 +0200 Subject: [PATCH 21/21] /type/cdist_type/ Signed-off-by: Steven Armstrong --- lib/cdist/core/object.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cdist/core/object.py b/lib/cdist/core/object.py index 2ae5f81b..a3baa941 100644 --- a/lib/cdist/core/object.py +++ b/lib/cdist/core/object.py @@ -63,8 +63,8 @@ class Object(object): if DOT_CDIST in dirs: yield os.path.relpath(path, object_base_path) - def __init__(self, type, base_path, object_id=None): - self.type = type # instance of Type + def __init__(self, cdist_type, base_path, object_id=None): + self.type = cdist_type # instance of Type self.base_path = base_path self.object_id = object_id self.name = os.path.join(self.type.name, self.object_id)