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)
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)))
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))