Ejemplo n.º 1
0
class  TestDataObjectCacheXmlSupport(unittest.TestCase):
    '''Tests to test DOC XML specific methods'''

    def setUp(self):
        '''Create DOC, and empty registry of classes, some children and refs'''

        # Hack to ensure that registry is empty before we use it,
        self.orig_registry = DOC._CACHE_CLASS_REGISTRY
        DOC._CACHE_CLASS_REGISTRY = dict()

        DataObjectCache.register_class([SimpleDataObject, SimpleDataObject2,
                SimpleDataObject3, SimpleDataObjectHandlesChildren])

        # Create a tree that looks like:
        #
        #    root
        #        child_1
        #            child_1_1
        #            child_1_2
        #        child_2
        #            child_2_1
        #                child_2_1_1
        #                    child_2_1_1_1
        #                    child_2_1_1_2
        #        child_3
        #            child_3_1
        #                child_3_1_2
        #                child_3_1_2
        #        child_4
        #        child_5
        #            child_5_1
        #            child_5_2
        #                child_5_2_1
        #                child_5_2_2
        #                child_5_2_3
        #                    child_5_2_3_1
        #                    child_5_2_3_2
        #                    child_5_2_3_3
        #        child_5_same_name

        # Create root node
        self.doc = DataObjectCache()

        # Create some persistent content
        self.persistent_root = SimpleDataObject("persistent_root")

        # Add some children, used by most tests.
        self.child_1 = SimpleDataObject2("child_1")
        self.child_2 = SimpleDataObject("child_2")
        self.child_3 = SimpleDataObject("child_3")
        self.child_4 = SimpleDataObject2("child_4")
        self.child_5 = SimpleDataObject3("child_5")

        self.do_list = list()
        self.do_list.append(self.child_1)
        self.do_list.append(self.child_2)
        self.do_list.append(self.child_3)
        self.do_list.append(self.child_4)
        self.do_list.append(self.child_5)

        self.persistent_root.insert_children(self.do_list)

        self.doc.persistent.insert_children(self.persistent_root)

       # Now let's add the children of children, etc. for use by
        # get_descendants() tests.
        # child_1 children
        self.child_1_1 = SimpleDataObject("child_1_1")
        self.child_1_2 = SimpleDataObject("child_1_2")
        self.child_1.insert_children([self.child_1_1, self.child_1_2])

        # child_2 tree
        self.child_2_1 = SimpleDataObject2("child_2_1")
        self.child_2.insert_children(self.child_2_1)
        self.child_2_1_1 = SimpleDataObject2("child_2_1_1")
        self.child_2_1.insert_children(self.child_2_1_1)
        self.child_2_1_1_1 = SimpleDataObject2("child_2_1_1_1")
        self.child_2_1_1_2 = SimpleDataObject2("child_2_1_1_2")
        self.child_2_1_1.insert_children([self.child_2_1_1_1,
            self.child_2_1_1_2])

        # child_3 tree
        self.child_3_1 = SimpleDataObject("child_3_1")
        self.child_3.insert_children(self.child_3_1)
        self.child_3_1_1 = SimpleDataObject("child_3_1_1")
        self.child_3_1_2 = SimpleDataObject("child_3_1_2")
        self.child_3_1_2_same_name = SimpleDataObject("child_3_1_2")
        self.child_3_1.insert_children([self.child_3_1_1, self.child_3_1_2,
        self.child_3_1_2_same_name])

        # child_5 tree
        self.child_5_1 = SimpleDataObject("child_5_1")
        self.child_5_2 = SimpleDataObject("child_5_2")
        self.child_5.insert_children([self.child_5_1, self.child_5_2])
        self.child_5_2_1 = SimpleDataObject("child_5_2_1")
        self.child_5_2_2 = SimpleDataObject("child_5_2_2")
        self.child_5_2_3 = SimpleDataObjectHandlesChildren("child_5_2_3")
        self.child_5_2.insert_children([self.child_5_2_1, self.child_5_2_2,
            self.child_5_2_3])

        self.child_5_2_3_1 = SimpleDataObject("child_5_2_3_1")
        self.child_5_2_3_2 = SimpleDataObject("child_5_2_3_2")
        self.child_5_2_3_3 = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3_3_same_name = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3.insert_children([self.child_5_2_3_1,
            self.child_5_2_3_2, self.child_5_2_3_3,
            self.child_5_2_3_3_same_name])

        # Create some volatile content, not much, just enough to test that it's
        # not overwritten on loading of snapshot.
        self.volatile_root = SimpleDataObject2("volatile_root")
        self.doc.volatile.insert_children(self.volatile_root)

    def tearDown(self):
        '''Restore class registry and clear DOC and other references'''

        # Hack to ensure that registry is restored after we use it.
        DOC._CACHE_CLASS_REGISTRY = self.orig_registry

        self.doc.clear()
        self.doc = None
        self.persistent_root = None
        self.volatile_root = None
        self.child_1 = None
        self.child_2 = None
        self.child_3 = None
        self.child_4 = None
        self.child_5 = None
        self.do_list = None

        self.child_1_1 = None
        self.child_1_2 = None

        self.child_2_1 = None
        self.child_2_1_1 = None
        self.child_2_1_1_1 = None
        self.child_2_1_1_2 = None

        self.child_3_1 = None
        self.child_3_1_1 = None
        self.child_3_1_2 = None
        self.child_3_1_2_same_name = None

        self.child_5_1 = None
        self.child_5_2 = None
        self.child_5_2_1 = None
        self.child_5_2_2 = None
        self.child_5_2_3 = None

        self.child_5_2_3_1 = None
        self.child_5_2_3_2 = None
        self.child_5_2_3_3 = None
        self.child_5_2_3_3_same_name = None

    def test_data_object_cache_xml_support_skip_sub_tree_elements(self):
        '''Validate no XML generated by volatile and persistent'''

        # doc.volatile and doc.persistent shouldn't generate their own
        # XML, so ensure tha this is the case.
        xml_tree = self.doc.generate_xml_manifest()

        child_names = []
        for xml_child in xml_tree:
            child_names.append(xml_child.get("name"))

        self.assertEqual(child_names, \
            [self.persistent_root.name, self.volatile_root.name])

    def test_data_object_cache_xml_support_generates_expected_xml(self):
        '''Validate that expected XML is generated by generate_xml_manifest'''
        indentation = '''\
        '''
        expected_xml = '''\
        <root>
        ..<SimpleDataObject name="persistent_root">
        ....<SimpleDataObject2 name="child_1">
        ......<SimpleDataObject name="child_1_1"/>
        ......<SimpleDataObject name="child_1_2"/>
        ....</SimpleDataObject2>
        ....<SimpleDataObject name="child_2">
        ......<SimpleDataObject2 name="child_2_1">
        ........<SimpleDataObject2 name="child_2_1_1">
        ..........<SimpleDataObject2 name="child_2_1_1_1"/>
        ..........<SimpleDataObject2 name="child_2_1_1_2"/>
        ........</SimpleDataObject2>
        ......</SimpleDataObject2>
        ....</SimpleDataObject>
        ....<SimpleDataObject name="child_3">
        ......<SimpleDataObject name="child_3_1">
        ........<SimpleDataObject name="child_3_1_1"/>
        ........<SimpleDataObject name="child_3_1_2"/>
        ........<SimpleDataObject name="child_3_1_2"/>
        ......</SimpleDataObject>
        ....</SimpleDataObject>
        ....<SimpleDataObject2 name="child_4"/>
        ....<SimpleDataObject name="child_5_1"/>
        ....<SimpleDataObject name="child_5_2">
        ......<SimpleDataObject name="child_5_2_1"/>
        ......<SimpleDataObject name="child_5_2_2"/>
        ......<SimpleDataObjectHandlesChildren name="child_5_2_3">
        ........<so_child name="child_5_2_3_1"/>
        ........<so_child name="child_5_2_3_2"/>
        ........<so_child name="child_5_2_3_3"/>
        ........<so_child name="child_5_2_3_3"/>
        ......</SimpleDataObjectHandlesChildren>
        ....</SimpleDataObject>
        ..</SimpleDataObject>
        ..<SimpleDataObject2 name="volatile_root"/>
        </root>
        '''.replace(indentation, "").replace(".", " ")

        xml_str = self.doc.get_xml_tree_str()

        self.assertEqual(xml_str, expected_xml,
            "Resulting XML doesn't match expected (len=%d != %d):\
             \nGOT:\n%s\nEXPECTED:\n%s\n" %
            (len(xml_str), len(expected_xml), xml_str, expected_xml))

    def test_data_object_cache_xml_support_children_from_xml_volatile(self):
        '''Validate import_from_manifest_xml volatile flag'''
        # Get original XML tree
        orig_xml_tree = self.doc.generate_xml_manifest()
        orig_xml_str = self.doc.get_xml_tree_str()

        # Empty the DOC
        self.doc.clear()

        self.assertTrue(self.doc.is_empty)

        # Now, try to re-create DOC from oricinal XML
        self.doc.import_from_manifest_xml(orig_xml_tree, volatile=True)

        self.assertTrue(self.doc.volatile.has_children)
        self.assertFalse(self.doc.persistent.has_children)

        imported_xml_str = self.doc.get_xml_tree_str()

        self.assertEqual(imported_xml_str, orig_xml_str,
            "Resulting XML doesn't match expected (len=%d != %d):\
             \nGOT:\n%s\nEXPECTED:\n%s\n" %
            (len(imported_xml_str), len(orig_xml_str),
             imported_xml_str, orig_xml_str))

    def test_data_object_cache_xml_support_children_from_xml_persistent(self):
        '''Validate default XML import into persistent tree'''
        # Get original XML tree
        orig_xml_tree = self.doc.generate_xml_manifest()
        orig_xml_str = self.doc.get_xml_tree_str()

        # Empty the DOC
        self.doc.clear()

        self.assertTrue(self.doc.is_empty)

        # Now, try to re-create DOC from oricinal XML
        self.doc.import_from_manifest_xml(orig_xml_tree)

        # Ensure it's in the correct tree
        self.assertFalse(self.doc.volatile.has_children)
        self.assertTrue(self.doc.persistent.has_children)

        imported_xml_str = self.doc.get_xml_tree_str()

        self.assertEqual(imported_xml_str, orig_xml_str,
            "Resulting XML doesn't match expected (len=%d != %d):\
             \nGOT:\n%s\nEXPECTED:\n%s\n" %
            (len(imported_xml_str), len(orig_xml_str),
             imported_xml_str, orig_xml_str))

    def test_data_object_cache_xml_methods(self):
        '''Validate correct values returned from XML methods'''
        self.assertNotEqual(self.doc.to_xml(), None)
        self.assertEqual(self.doc.persistent.to_xml(), None)
        self.assertEqual(self.doc.volatile.to_xml(), None)

        self.assertFalse(self.doc.can_handle(None))
        self.assertFalse(self.doc.from_xml(None))

        self.assertFalse(self.doc.persistent.can_handle(None))
        self.assertFalse(self.doc.persistent.from_xml(None))

        self.assertFalse(self.doc.volatile.can_handle(None))
        self.assertFalse(self.doc.volatile.from_xml(None))
class TestDataObjectCacheSnapshots(unittest.TestCase):
    '''Tests to validate DOC snapshots support'''

    def setUp(self):
        '''Set up correct environment for tests.

        Creates reference to a temp dir and file and StringIO buffer.

        Creates a tree of elements in the DOC to validate before/after.
        '''

        # Create temporary work directory
        self.temp_dir = mkdtemp(prefix="doc_test-")
        self.temp_file = mktemp(prefix="snapshot-", dir=self.temp_dir)

        # Create StringIO memory buffer for I/O test
        self.buffer = StringIO()

        # Create a tree that looks like:
        #  DOC
        #    volatile
        #      volatile_root
        #    persistent
        #      persistent_root
        #        child_1
        #            child_1_1
        #            child_1_2
        #        child_2
        #            child_2_1
        #                child_2_1_1
        #                    child_2_1_1_1
        #                    child_2_1_1_2
        #        child_3
        #            child_3_1
        #                child_3_1_2
        #                child_3_1_2
        #                child_3_1_2_same_name
        #        child_4
        #        child_5
        #            child_5_1
        #            child_5_2
        #                child_5_2_1
        #                child_5_2_2
        #                child_5_2_3
        #                    child_5_2_3_1
        #                    child_5_2_3_2
        #                    child_5_2_3_3
        #                    child_5_2_3_3_same_name
        #        child_5_same_name

        # Create DOC node
        self.doc = DataObjectCache()

        # Create some persistent content
        self.persistent_root = SimpleDataObject("persistent_root")
        # Add some children, used by most tests.
        self.child_1 = SimpleDataObject2("child_1")
        self.child_2 = SimpleDataObject("child_2")
        self.child_3 = SimpleDataObject("child_3")
        self.child_4 = SimpleDataObject2("child_4")
        self.child_5 = SimpleDataObject3("child_5")
        self.child_5_same_name = SimpleDataObject("child_5")

        self.do_list = list()
        self.do_list.append(self.child_1)
        self.do_list.append(self.child_2)
        self.do_list.append(self.child_3)
        self.do_list.append(self.child_4)
        self.do_list.append(self.child_5)
        self.do_list.append(self.child_5_same_name)

        self.persistent_root.insert_children(self.do_list)

        self.doc.persistent.insert_children(self.persistent_root)

        # Now let's add the children of children, etc. for use by
        # get_descendants() tests.
        # child_1 children
        self.child_1_1 = SimpleDataObject("child_1_1")
        self.child_1_2 = SimpleDataObject("child_1_2")
        self.child_1.insert_children([self.child_1_1, self.child_1_2])

        # child_2 tree
        self.child_2_1 = SimpleDataObject2("child_2_1")
        self.child_2.insert_children(self.child_2_1)
        self.child_2_1_1 = SimpleDataObject2("child_2_1_1")
        self.child_2_1.insert_children(self.child_2_1_1)
        self.child_2_1_1_1 = SimpleDataObject2("child_2_1_1_1")
        self.child_2_1_1_2 = SimpleDataObject2("child_2_1_1_2")
        self.child_2_1_1.insert_children(
            [self.child_2_1_1_1, self.child_2_1_1_2])

        # child_3 tree
        self.child_3_1 = SimpleDataObject("child_3_1")
        self.child_3.insert_children(self.child_3_1)
        self.child_3_1_1 = SimpleDataObject("child_3_1_1")
        self.child_3_1_2 = SimpleDataObject("child_3_1_2")
        self.child_3_1_2_same_name = SimpleDataObject("child_3_1_2")
        self.child_3_1.insert_children([self.child_3_1_1, self.child_3_1_2,
        self.child_3_1_2_same_name])

        # child_5 tree
        self.child_5_1 = SimpleDataObject("child_5_1")
        self.child_5_2 = SimpleDataObject("child_5_2")
        self.child_5.insert_children([self.child_5_1, self.child_5_2])
        self.child_5_2_1 = SimpleDataObject("child_5_2_1")
        self.child_5_2_2 = SimpleDataObject("child_5_2_2")
        self.child_5_2_3 = SimpleDataObject4("child_5_2_3")
        self.child_5_2.insert_children(
            [self.child_5_2_1, self.child_5_2_2, self.child_5_2_3])

        self.child_5_2_3_1 = SimpleDataObject("child_5_2_3_1")
        self.child_5_2_3_2 = SimpleDataObject("child_5_2_3_2")
        self.child_5_2_3_3 = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3_3_same_name = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3.insert_children(
            [self.child_5_2_3_1, self.child_5_2_3_2,
        self.child_5_2_3_3, self.child_5_2_3_3_same_name])

        # Create some volatile content, not much, just enough to test that it's
        # not overwritten on loading of snapshot.
        self.volatile_root = SimpleDataObject2("volatile_root")
        self.doc.volatile.insert_children(self.volatile_root)

    def tearDown(self):
        '''Cleanup test environment and references.'''
        # Remove temp dir, may not always be there.
        if path.exists(self.temp_file):
            unlink(self.temp_file)

        if path.exists(self.temp_dir):
            rmdir(self.temp_dir)

        # Remove buffer
        self.buffer.close()  # Free's memory
        self.buffer = None

        # Unset variables.
        self.doc.clear()
        self.doc = None
        self.volatile_root = None
        self.persistent_root = None
        self.child_1 = None
        self.child_2 = None
        self.child_3 = None
        self.child_4 = None
        self.child_5 = None
        self.child_5_same_name = None
        self.do_list = None

        self.child_1_1 = None
        self.child_1_2 = None

        self.child_2_1 = None
        self.child_2_1_1 = None
        self.child_2_1_1_1 = None
        self.child_2_1_1_2 = None

        self.child_3_1 = None
        self.child_3_1_1 = None
        self.child_3_1_2 = None
        self.child_3_1_2_same_name = None

        self.child_5_1 = None
        self.child_5_2 = None
        self.child_5_2_1 = None
        self.child_5_2_2 = None
        self.child_5_2_3 = None

        self.child_5_2_3_1 = None
        self.child_5_2_3_2 = None
        self.child_5_2_3_3 = None
        self.child_5_2_3_3_same_name = None

    def test_data_object_cache_snapshots_write_file_string(self):
        '''Validate writing of a snapshot to a file'''
        try:
            self.doc.take_snapshot(self.temp_file)
        except Exception, e:
            self.fail("Got unexpected error writing snapshot: " + str(e))

        try:
            stat_info = stat(self.temp_file)
            self.assertFalse(stat_info.st_size < 2048,
                "Snapshot file size is too small: %d" % (stat_info.st_size))
        except Exception, e:
            self.fail("Got unexpected error stat-ing snapshot file: " + str(e))
class TestDataObjectCacheRegistration(unittest.TestCase):
    '''Tests to validate DataObjectCache registration mechanism'''

    def setUp(self):
        '''Create DOC reference, and ensure an empty class registry'''
        self.doc = DataObjectCache()

        # Hack to ensure that registry is empty before we use it,
        self.orig_registry = DOC._CACHE_CLASS_REGISTRY
        DOC._CACHE_CLASS_REGISTRY = dict()

    def tearDown(self):
        '''Cleanup DOC reference, but restore DOC's class registry when done'''
        self.doc.clear()
        self.doc = None

        # Hack to ensure that registry is restored after we use it.
        DOC._CACHE_CLASS_REGISTRY = self.orig_registry

    def test_doc_registration_simple_data_object(self):
        '''Validate registration and selection of a single class'''
        try:
            DataObjectCache.register_class(SimpleDataObject)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject!")

        # Test that it's actually registered and will correclty return class.
        simple = SimpleDataObject("TestSimple")
        xml_elem = simple.to_xml()
        class_obj = DataObjectCache.find_class_to_handle(xml_elem)
        self.assertEqual(class_obj, SimpleDataObject, str(class_obj))

    def test_doc_registration_simple_data_object_prio_30(self):
        '''Validate insertion of a class with prio 30'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=30)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 30!")

    def test_doc_registration_simple_data_object_prio_0(self):
        '''Validate insertion of a class with prio 0'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=0)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 0!")

    def test_doc_registration_simple_data_object_prio_100(self):
        '''Validate insertion of a class with prio 100'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=100)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 100!")

    def test_doc_registration_simple_data_object_prio_minus_1(self):
        '''Validate insertion fails with a class with prio -1'''
        self.assertRaises(ValueError, DataObjectCache.register_class,
            SimpleDataObject, priority=-1)

    def test_doc_registration_simple_data_object_prio_101(self):
        '''Validate insertion fails with a class with prio 101'''
        self.assertRaises(ValueError, DataObjectCache.register_class,
            SimpleDataObject, priority=101)

    def test_doc_registration_non_data_object(self):
        '''Validate insertion fails with a non-DataObject sub-class'''
        self.assertRaises(TypeError, DataObjectCache.register_class,
            object)

    def test_doc_registration_get_registered_classes_str(self):
        '''Validate correct output from get_registered_classes_str()'''
        # Used as expected return string in method
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
        [Priority = 50]
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
        [Priority = 100]
            <class 'simple_data_object.SimpleDataObject4'>
        ============================
        '''.replace(indentation, "")

        DataObjectCache.register_class(SimpleDataObject, priority=30)
        DataObjectCache.register_class(SimpleDataObject2)
        DataObjectCache.register_class(SimpleDataObject3, priority=50)
        DataObjectCache.register_class(SimpleDataObject4, priority=100)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(expected_registered_classes_str, txt,
            "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_classes_from_module_same_prio(self):
        '''Validate registration of classes in a module at same priority'''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
            <class 'simple_data_object.SimpleDataObject5'>
            <class 'simple_data_object.SimpleDataObjectHandlesChildren'>
            <class 'simple_data_object.SimpleDataObjectNoXml'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class(simple_data_object, priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(expected_registered_classes_str, txt,
            "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_classes_from_module_in_list_same_prio(self):
        '''Validate registration of classes in a module list at same priority
        '''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
            <class 'simple_data_object.SimpleDataObject5'>
            <class 'simple_data_object.SimpleDataObjectHandlesChildren'>
            <class 'simple_data_object.SimpleDataObjectNoXml'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class([simple_data_object], priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(expected_registered_classes_str, txt,
            "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_multiple_classes_same_prio(self):
        '''Validate registration of multiple classes at same priority'''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class(SimpleDataObject, priority=30)
        DataObjectCache.register_class(SimpleDataObject2, priority=30)
        DataObjectCache.register_class(SimpleDataObject3, priority=30)
        DataObjectCache.register_class(SimpleDataObject4, priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(expected_registered_classes_str, txt,
            "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_multiple_handlers_highest_prio_selected(self):
        '''Validate highest priority class is selected when several handlers'''
        DataObjectCache.register_class(SimpleDataObjectSameTagHighPrio,
            priority=30)
        DataObjectCache.register_class(SimpleDataObjectSameTagNormPrio,
            priority=50)

        xml_elem = etree.Element(COMMON_TAG, name="some name")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem)

        self.assertEqual(class_obj, SimpleDataObjectSameTagHighPrio)

    def test_doc_registration_no_handler_found(self):
        '''Validate failure of no handler is found'''
        DataObjectCache.register_class(SimpleDataObject)
        DataObjectCache.register_class(SimpleDataObject2)
        DataObjectCache.register_class(SimpleDataObject3)
        DataObjectCache.register_class(SimpleDataObject4)

        # First ensure it works as expected.
        xml_elem = etree.Element("SimpleDataObject", name="handled")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem)

        self.assertEqual(class_obj, SimpleDataObject)

        # Now ensure that it fails when expected.
        xml_elem_fail = etree.Element("not_handled", name="not_handled_name")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem_fail)

        self.assertEqual(class_obj, None)
Ejemplo n.º 4
0
class TestDataObjectCacheRegistration(unittest.TestCase):
    '''Tests to validate DataObjectCache registration mechanism'''
    def setUp(self):
        '''Create DOC reference, and ensure an empty class registry'''
        self.doc = DataObjectCache()

        # Hack to ensure that registry is empty before we use it,
        self.orig_registry = DOC._CACHE_CLASS_REGISTRY
        DOC._CACHE_CLASS_REGISTRY = dict()

    def tearDown(self):
        '''Cleanup DOC reference, but restore DOC's class registry when done'''
        self.doc.clear()
        self.doc = None

        # Hack to ensure that registry is restored after we use it.
        DOC._CACHE_CLASS_REGISTRY = self.orig_registry

    def test_doc_registration_simple_data_object(self):
        '''Validate registration and selection of a single class'''
        try:
            DataObjectCache.register_class(SimpleDataObject)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject!")

        # Test that it's actually registered and will correclty return class.
        simple = SimpleDataObject("TestSimple")
        xml_elem = simple.to_xml()
        class_obj = DataObjectCache.find_class_to_handle(xml_elem)
        self.assertEqual(class_obj, SimpleDataObject, str(class_obj))

    def test_doc_registration_simple_data_object_prio_30(self):
        '''Validate insertion of a class with prio 30'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=30)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 30!")

    def test_doc_registration_simple_data_object_prio_0(self):
        '''Validate insertion of a class with prio 0'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=0)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 0!")

    def test_doc_registration_simple_data_object_prio_100(self):
        '''Validate insertion of a class with prio 100'''
        try:
            DataObjectCache.register_class(SimpleDataObject, priority=100)
        except (TypeError, ValueError):
            self.fail("Failed to register SimpleDataObject with prio 100!")

    def test_doc_registration_simple_data_object_prio_minus_1(self):
        '''Validate insertion fails with a class with prio -1'''
        self.assertRaises(ValueError,
                          DataObjectCache.register_class,
                          SimpleDataObject,
                          priority=-1)

    def test_doc_registration_simple_data_object_prio_101(self):
        '''Validate insertion fails with a class with prio 101'''
        self.assertRaises(ValueError,
                          DataObjectCache.register_class,
                          SimpleDataObject,
                          priority=101)

    def test_doc_registration_non_data_object(self):
        '''Validate insertion fails with a non-DataObject sub-class'''
        self.assertRaises(TypeError, DataObjectCache.register_class, object)

    def test_doc_registration_get_registered_classes_str(self):
        '''Validate correct output from get_registered_classes_str()'''
        # Used as expected return string in method
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
        [Priority = 50]
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
        [Priority = 100]
            <class 'simple_data_object.SimpleDataObject4'>
        ============================
        '''.replace(indentation, "")

        DataObjectCache.register_class(SimpleDataObject, priority=30)
        DataObjectCache.register_class(SimpleDataObject2)
        DataObjectCache.register_class(SimpleDataObject3, priority=50)
        DataObjectCache.register_class(SimpleDataObject4, priority=100)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(
            expected_registered_classes_str, txt, "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_classes_from_module_same_prio(self):
        '''Validate registration of classes in a module at same priority'''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
            <class 'simple_data_object.SimpleDataObject5'>
            <class 'simple_data_object.SimpleDataObjectHandlesChildren'>
            <class 'simple_data_object.SimpleDataObjectNoXml'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class(simple_data_object, priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(
            expected_registered_classes_str, txt, "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_classes_from_module_in_list_same_prio(self):
        '''Validate registration of classes in a module list at same priority
        '''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
            <class 'simple_data_object.SimpleDataObject5'>
            <class 'simple_data_object.SimpleDataObjectHandlesChildren'>
            <class 'simple_data_object.SimpleDataObjectNoXml'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class([simple_data_object], priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(
            expected_registered_classes_str, txt, "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_multiple_classes_same_prio(self):
        '''Validate registration of multiple classes at same priority'''
        # Compensate for indent
        indentation = '''\
        '''
        expected_registered_classes_str = '''\
        ============================
        Registered Classes:
        [Priority = 30]
            <class 'simple_data_object.SimpleDataObject'>
            <class 'simple_data_object.SimpleDataObject2'>
            <class 'simple_data_object.SimpleDataObject3'>
            <class 'simple_data_object.SimpleDataObject4'>
        ============================
        '''.replace(indentation, "")
        DataObjectCache.register_class(SimpleDataObject, priority=30)
        DataObjectCache.register_class(SimpleDataObject2, priority=30)
        DataObjectCache.register_class(SimpleDataObject3, priority=30)
        DataObjectCache.register_class(SimpleDataObject4, priority=30)

        txt = self.doc.get_registered_classes_str()

        self.assertEquals(
            expected_registered_classes_str, txt, "EXPECTED:\n%s\nGOT:\n%s\n" %
            (expected_registered_classes_str, txt))

    def test_doc_registration_multiple_handlers_highest_prio_selected(self):
        '''Validate highest priority class is selected when several handlers'''
        DataObjectCache.register_class(SimpleDataObjectSameTagHighPrio,
                                       priority=30)
        DataObjectCache.register_class(SimpleDataObjectSameTagNormPrio,
                                       priority=50)

        xml_elem = etree.Element(COMMON_TAG, name="some name")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem)

        self.assertEqual(class_obj, SimpleDataObjectSameTagHighPrio)

    def test_doc_registration_no_handler_found(self):
        '''Validate failure of no handler is found'''
        DataObjectCache.register_class(SimpleDataObject)
        DataObjectCache.register_class(SimpleDataObject2)
        DataObjectCache.register_class(SimpleDataObject3)
        DataObjectCache.register_class(SimpleDataObject4)

        # First ensure it works as expected.
        xml_elem = etree.Element("SimpleDataObject", name="handled")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem)

        self.assertEqual(class_obj, SimpleDataObject)

        # Now ensure that it fails when expected.
        xml_elem_fail = etree.Element("not_handled", name="not_handled_name")

        class_obj = DataObjectCache.find_class_to_handle(xml_elem_fail)

        self.assertEqual(class_obj, None)
class  TestDataObjectCacheUtility(unittest.TestCase):
    '''Tests for DOC utility functionality'''

    def setUp(self):
        '''Create small set of objects and references to them'''
        self.doc = DataObjectCache()
        self.persistent_child_1 = SimpleDataObject("persistent_child_1")
        self.persistent_child_2 = SimpleDataObject("persistent_child_2")
        self.persistent_child_3 = SimpleDataObject("persistent_child_3")
        self.doc.persistent.insert_children([self.persistent_child_1,
            self.persistent_child_2, self.persistent_child_3])

        self.volatile_child_1 = SimpleDataObject("volatile_child_1")
        self.volatile_child_2 = SimpleDataObject("volatile_child_2")
        self.volatile_child_3 = SimpleDataObject("volatile_child_3")
        self.doc.volatile.insert_children([self.volatile_child_1,
            self.volatile_child_2, self.volatile_child_3])

    def tearDown(self):
        '''Clean up contents of DOC and reference'''
        self.doc.clear()
        self.doc = None

        self.persistent_child_1 = None
        self.persistent_child_2 = None
        self.persistent_child_3 = None

        self.volatile_child_1 = None
        self.volatile_child_2 = None
        self.volatile_child_3 = None

    def test_data_object_cache_utility_clear(self):
        '''Validate the doc.clear() clears children of sub-trees only'''
        self.assertTrue(self.doc.has_children,
            "DataObjectCache should always have children\n%s" %\
            (str(self.doc)))
        self.assertTrue(self.doc.persistent.has_children,
            "Persistent sub-tree should have children\n%s" %\
            (str(self.doc)))
        self.assertTrue(self.doc.volatile.has_children,
            "Volatile sub-tree should have children\n%s" %\
            (str(self.doc)))

        self.doc.clear()

        self.assertFalse(self.doc.persistent.has_children,
            "Persistent sub-tree should have no children:\n%s" %\
            (str(self.doc)))
        self.assertFalse(self.doc.volatile.has_children,
            "Volatile sub-tree should have no children\n%s" %\
            (str(self.doc)))
        self.assertTrue(self.doc.has_children,
            "DataObjectCache should always have children\n%s" %\
            (str(self.doc)))

    def test_data_object_cache_utility_is_empty(self):
        '''Validate that doc.is_empty property is valid'''
        self.assertFalse(self.doc.is_empty,
            "DOC doesn't contain children, when it should: \n%s" %
            (str(self.doc)))
        self.doc.clear()
        self.assertTrue(self.doc.is_empty,
            "DOC contains children when it should be empty: \n%s" %
            (str(self.doc)))
Ejemplo n.º 6
0
class TestDataObjectCacheChildren(unittest.TestCase):
    '''Tests to validata the DOC children operate as expected'''
    def setUp(self):
        '''Create a reference to a DOC'''
        self.doc = DataObjectCache()

    def tearDown(self):
        '''Cleanup reference to DOC and it's children'''
        self.doc.clear()
        self.doc = None

    def test_data_object_cache_children_exist(self):
        '''Validate that the DOC children always exist'''
        persistent = self.doc.get_children(name="persistent")
        volatile = self.doc.get_children(name="volatile")

        self.assertTrue(len(persistent) > 0 and persistent[0] != None)
        self.assertTrue(len(volatile) > 0 and volatile[0] != None)

        self.assertEqual(persistent[0], self.doc.persistent)
        self.assertEqual(volatile[0], self.doc.volatile)

    def test_data_object_cache_children_insertion(self):
        '''Validate that DOC doesn't allow insertion of direct children'''
        simple = SimpleDataObject("Test Child")
        try:
            self.doc.insert_children(simple)
            self.fail("Managed to insert child when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_deletion_directly(self):
        '''Validate the DOC children cannot be deleted by reference'''
        try:
            self.doc.delete_children(self.doc.persistent)
            self.fail("Managed to delete 'persistent' when expected exception")
        except AttributeError:
            pass

        try:
            self.doc.delete_children(self.doc.volatile)
            self.fail("Managed to delete 'volatile' when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_deletion_all(self):
        '''Validate the DOC children cannot be deleted by delete all.'''
        try:
            self.doc.delete_children()
            self.fail("Managed to delete children when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_delete(self):
        '''Validate DOC and children cannot be deleted by delete() method'''
        try:
            self.doc.delete()
            self.fail("Managed to delete self when expected exception")
        except AttributeError:
            pass

        # Ensure that delete() call doesn't delete persistent and volatile.
        self.doc.persistent.delete()
        self.assertNotEqual(self.doc.persistent, None)

        self.doc.volatile.delete()
        self.assertNotEqual(self.doc.volatile, None)
class  TestDataObjectCacheChildren(unittest.TestCase):
    '''Tests to validata the DOC children operate as expected'''

    def setUp(self):
        '''Create a reference to a DOC'''
        self.doc = DataObjectCache()

    def tearDown(self):
        '''Cleanup reference to DOC and it's children'''
        self.doc.clear()
        self.doc = None

    def test_data_object_cache_children_exist(self):
        '''Validate that the DOC children always exist'''
        persistent = self.doc.get_children(name="persistent")
        volatile = self.doc.get_children(name="volatile")

        self.assertTrue(len(persistent) > 0 and persistent[0] != None)
        self.assertTrue(len(volatile) > 0 and volatile[0] != None)

        self.assertEqual(persistent[0], self.doc.persistent)
        self.assertEqual(volatile[0], self.doc.volatile)

    def test_data_object_cache_children_insertion(self):
        '''Validate that DOC doesn't allow insertion of direct children'''
        simple = SimpleDataObject("Test Child")
        try:
            self.doc.insert_children(simple)
            self.fail("Managed to insert child when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_deletion_directly(self):
        '''Validate the DOC children cannot be deleted by reference'''
        try:
            self.doc.delete_children(self.doc.persistent)
            self.fail("Managed to delete 'persistent' when expected exception")
        except AttributeError:
            pass

        try:
            self.doc.delete_children(self.doc.volatile)
            self.fail("Managed to delete 'volatile' when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_deletion_all(self):
        '''Validate the DOC children cannot be deleted by delete all.'''
        try:
            self.doc.delete_children()
            self.fail("Managed to delete children when expected exception")
        except AttributeError:
            pass

    def test_data_object_cache_children_delete(self):
        '''Validate DOC and children cannot be deleted by delete() method'''
        try:
            self.doc.delete()
            self.fail("Managed to delete self when expected exception")
        except AttributeError:
            pass

        # Ensure that delete() call doesn't delete persistent and volatile.
        self.doc.persistent.delete()
        self.assertNotEqual(self.doc.persistent, None)

        self.doc.volatile.delete()
        self.assertNotEqual(self.doc.volatile, None)
class TestDataObjectCacheSnapshots(unittest.TestCase):
    '''Tests to validate DOC snapshots support'''
    def setUp(self):
        '''Set up correct environment for tests.

        Creates reference to a temp dir and file and StringIO buffer.

        Creates a tree of elements in the DOC to validate before/after.
        '''

        # Create temporary work directory
        self.temp_dir = mkdtemp(prefix="doc_test-")
        self.temp_file = mktemp(prefix="snapshot-", dir=self.temp_dir)

        # Create StringIO memory buffer for I/O test
        self.buffer = StringIO()

        # Create a tree that looks like:
        #  DOC
        #    volatile
        #      volatile_root
        #    persistent
        #      persistent_root
        #        child_1
        #            child_1_1
        #            child_1_2
        #        child_2
        #            child_2_1
        #                child_2_1_1
        #                    child_2_1_1_1
        #                    child_2_1_1_2
        #        child_3
        #            child_3_1
        #                child_3_1_2
        #                child_3_1_2
        #                child_3_1_2_same_name
        #        child_4
        #        child_5
        #            child_5_1
        #            child_5_2
        #                child_5_2_1
        #                child_5_2_2
        #                child_5_2_3
        #                    child_5_2_3_1
        #                    child_5_2_3_2
        #                    child_5_2_3_3
        #                    child_5_2_3_3_same_name
        #        child_5_same_name

        # Create DOC node
        self.doc = DataObjectCache()

        # Create some persistent content
        self.persistent_root = SimpleDataObject("persistent_root")
        # Add some children, used by most tests.
        self.child_1 = SimpleDataObject2("child_1")
        self.child_2 = SimpleDataObject("child_2")
        self.child_3 = SimpleDataObject("child_3")
        self.child_4 = SimpleDataObject2("child_4")
        self.child_5 = SimpleDataObject3("child_5")
        self.child_5_same_name = SimpleDataObject("child_5")

        self.do_list = list()
        self.do_list.append(self.child_1)
        self.do_list.append(self.child_2)
        self.do_list.append(self.child_3)
        self.do_list.append(self.child_4)
        self.do_list.append(self.child_5)
        self.do_list.append(self.child_5_same_name)

        self.persistent_root.insert_children(self.do_list)

        self.doc.persistent.insert_children(self.persistent_root)

        # Now let's add the children of children, etc. for use by
        # get_descendants() tests.
        # child_1 children
        self.child_1_1 = SimpleDataObject("child_1_1")
        self.child_1_2 = SimpleDataObject("child_1_2")
        self.child_1.insert_children([self.child_1_1, self.child_1_2])

        # child_2 tree
        self.child_2_1 = SimpleDataObject2("child_2_1")
        self.child_2.insert_children(self.child_2_1)
        self.child_2_1_1 = SimpleDataObject2("child_2_1_1")
        self.child_2_1.insert_children(self.child_2_1_1)
        self.child_2_1_1_1 = SimpleDataObject2("child_2_1_1_1")
        self.child_2_1_1_2 = SimpleDataObject2("child_2_1_1_2")
        self.child_2_1_1.insert_children(
            [self.child_2_1_1_1, self.child_2_1_1_2])

        # child_3 tree
        self.child_3_1 = SimpleDataObject("child_3_1")
        self.child_3.insert_children(self.child_3_1)
        self.child_3_1_1 = SimpleDataObject("child_3_1_1")
        self.child_3_1_2 = SimpleDataObject("child_3_1_2")
        self.child_3_1_2_same_name = SimpleDataObject("child_3_1_2")
        self.child_3_1.insert_children(
            [self.child_3_1_1, self.child_3_1_2, self.child_3_1_2_same_name])

        # child_5 tree
        self.child_5_1 = SimpleDataObject("child_5_1")
        self.child_5_2 = SimpleDataObject("child_5_2")
        self.child_5.insert_children([self.child_5_1, self.child_5_2])
        self.child_5_2_1 = SimpleDataObject("child_5_2_1")
        self.child_5_2_2 = SimpleDataObject("child_5_2_2")
        self.child_5_2_3 = SimpleDataObject4("child_5_2_3")
        self.child_5_2.insert_children(
            [self.child_5_2_1, self.child_5_2_2, self.child_5_2_3])

        self.child_5_2_3_1 = SimpleDataObject("child_5_2_3_1")
        self.child_5_2_3_2 = SimpleDataObject("child_5_2_3_2")
        self.child_5_2_3_3 = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3_3_same_name = SimpleDataObject("child_5_2_3_3")
        self.child_5_2_3.insert_children([
            self.child_5_2_3_1, self.child_5_2_3_2, self.child_5_2_3_3,
            self.child_5_2_3_3_same_name
        ])

        # Create some volatile content, not much, just enough to test that it's
        # not overwritten on loading of snapshot.
        self.volatile_root = SimpleDataObject2("volatile_root")
        self.doc.volatile.insert_children(self.volatile_root)

    def tearDown(self):
        '''Cleanup test environment and references.'''
        # Remove temp dir, may not always be there.
        if path.exists(self.temp_file):
            unlink(self.temp_file)

        if path.exists(self.temp_dir):
            rmdir(self.temp_dir)

        # Remove buffer
        self.buffer.close()  # Free's memory
        self.buffer = None

        # Unset variables.
        self.doc.clear()
        self.doc = None
        self.volatile_root = None
        self.persistent_root = None
        self.child_1 = None
        self.child_2 = None
        self.child_3 = None
        self.child_4 = None
        self.child_5 = None
        self.child_5_same_name = None
        self.do_list = None

        self.child_1_1 = None
        self.child_1_2 = None

        self.child_2_1 = None
        self.child_2_1_1 = None
        self.child_2_1_1_1 = None
        self.child_2_1_1_2 = None

        self.child_3_1 = None
        self.child_3_1_1 = None
        self.child_3_1_2 = None
        self.child_3_1_2_same_name = None

        self.child_5_1 = None
        self.child_5_2 = None
        self.child_5_2_1 = None
        self.child_5_2_2 = None
        self.child_5_2_3 = None

        self.child_5_2_3_1 = None
        self.child_5_2_3_2 = None
        self.child_5_2_3_3 = None
        self.child_5_2_3_3_same_name = None

    def test_data_object_cache_snapshots_write_file_string(self):
        '''Validate writing of a snapshot to a file'''
        try:
            self.doc.take_snapshot(self.temp_file)
        except Exception, e:
            self.fail("Got unexpected error writing snapshot: " + str(e))

        try:
            stat_info = stat(self.temp_file)
            self.assertFalse(
                stat_info.st_size < 2048,
                "Snapshot file size is too small: %d" % (stat_info.st_size))
        except Exception, e:
            self.fail("Got unexpected error stat-ing snapshot file: " + str(e))