def test_inherit_existing(self): """Inherit from existing entry /root (height=50) /group (height=100) /subgroup <-- Inherits above """ group = os.path.join(self.root_path, 'group') subgroup = os.path.join(group, 'subgroup') os.makedirs(subgroup) base_location = self.root group_location = om.Location(group) subgroup_location = om.Location(subgroup) base_value = om.Entry('height', value=50, parent=base_location) group_value = om.Entry('height', value=100, parent=group_location) om.flush(base_value) om.flush(group_value) # Get metadata from location where metadata doesn't exist height = om.Entry('height', parent=subgroup_location) om.inherit(height) self.assertEquals(height.value, 100)
def test_add_entries_to_nongroup(self): """Add entries to nongroup Adding entries to an entry that isn't a group will cast it to a group. """ nongroup_entry = om.Entry('nongroup', value='A string', parent=self.root) self.assertTrue(nongroup_entry.type == 'string') om.flush(nongroup_entry) invalid_child = om.Entry('invalid_child', value='a string', parent=nongroup_entry) # By adding a child, the nongroup becomes a group. # Just like it would in a dynamic programming language: # >>> myint = 5 # >>> myint = list() self.assertEquals(nongroup_entry.type, 'dict') om.flush(nongroup_entry) self.assertTrue(os.path.exists(nongroup_entry.path.as_str)) om.pull(nongroup_entry) self.assertTrue(os.path.exists(invalid_child.path.as_str)) self.assertTrue(os.path.isdir(nongroup_entry.path.as_str)) self.assertEquals(nongroup_entry.type, 'dict')
def test_change_type_by_overwriting(self): """Types in Open Metadata are represented on disk as suffixes. However a suffix is an implementation detail and should not be modified by hand. The equivalence in dynamic programming languages is this: >> myint = 5 >> myint = "I'm a string now" On disk, myint would initially be stored as `myint.int` but after having been reassigned a string value, it would be stored as `myint.string`. The point to take home being that suffixes are a serialisation of type and dictates how the file is to be read. """ height = om.Entry('height', value=10, parent=self.root) om.flush(height) self.assertEquals(height.type, 'int') height = om.Entry('height', value=11.1, parent=self.root) om.flush(height) self.assertEquals(height.type, 'float')
def test_absolutename(self): """If entry exists, suffix will be implied by find()""" entry = om.Entry('custom.int', value=10, parent=self.root) om.flush(entry) entry = om.Entry('custom.string', value="Hello", parent=self.root) om.pull(entry) self.assertEquals(entry.type, 'int')
def test_removal_group(self): removed = om.Entry('removed.dict', parent=self.root) om.Entry('child', value=1, parent=removed) self.assertEquals(removed.type, 'dict') om.flush(removed) self.assertTrue(os.path.isdir(removed.path.as_str)) om.recycle(removed) self.assertFalse(os.path.exists(removed.path.as_str))
def test_new_group_with_content(self): """The alternative is to add other entries to is""" entry = om.Entry('a group', parent=self.root) for key, value in self.data.iteritems(): om.Entry(key, value=value, parent=entry) om.flush(entry) self.assertTrue(entry.type == 'dict') self.assertTrue(os.path.exists(entry.path.as_str))
def test_flush_existing(self): """Overwrite existing entry""" # Make it exist standard_int = om.Entry('standard_int', value=10, parent=self.root) om.flush(standard_int) self.assertTrue(os.path.exists(standard_int.path.as_str)) # Then flush it again standard_int = om.Entry('standard_int', value=15, parent=self.root) om.flush(standard_int) om.pull(standard_int) self.assertEquals(standard_int.value, 15)
def test_case_sensitivity(self): case_sensitive_location = om.Location(self.case_path) data = om.Entry('data', parent=case_sensitive_location) om.pull(data) self.assertEquals(data.value, 'value here') wrong_case = om.Location(self.case_path.lower()) data = om.Entry('data', parent=wrong_case) if sys.platform == 'win32': om.pull(data) self.assertEquals(data.value, 'value here') else: self.assertRaises(om.error.Exists, om.pull, data)
def test_removal(self): removed = om.Entry('removed', value=1, parent=self.root) om.flush(removed) self.assertTrue(os.path.isfile(removed.path.as_str)) om.recycle(removed) self.assertFalse(os.path.exists(removed.path.as_str))
def test_pull_unknown_string(self): """Pull from entry whose value is string but suffix is misnamed""" entry = om.Entry('unknown_string.abc', parent=self.project) self.assertTrue(os.path.exists(entry.path.as_str)) om.pull(entry) self.assertEquals(entry.value, u'this is of type string') self.assertEquals(entry.path.suffix, 'string')
def test_pull_existing(self): """Read from existing metadata""" entry = om.Entry("standard_int.int", parent=self.project) om.pull(entry) self.assertEquals(entry.value, 10) self.assertEquals(entry.path.basename, "standard_int.int") self.assertEquals(entry.path.suffix, "int")
def test_convert(self): """contert() is a shorthand for creating location and entry sep.""" entry = om.Entry('custom.int', value=10, parent=self.root) om.flush(entry) entry = om.convert(entry.path.as_str) self.assertEquals(entry.value, 10)
def test_convert_withmissingsuffix(self): entry = om.Entry('custom_missing.int', value=10, parent=self.root) om.flush(entry) new_path = entry.path.copy(suffix='string') entry = om.convert(new_path.as_str) self.assertEquals(entry.value, 10)
def test_modify_existing(self): """Modifying an existing value with a value of the same type should leave the original suffix intact""" entry = om.Entry('standard_int.int', parent=self.project) entry.value = 15 self.assertEquals(entry.value, 15) self.assertEquals(entry.path.basename, "standard_int.int") self.assertEquals(entry.path.suffix, "int")
def test_new_group(self): """Write a new group""" entry = om.Entry('a group.dict', parent=self.root) om.flush(entry) om.pull(entry) self.assertEquals(entry.type, 'dict') self.assertTrue(os.path.isdir(entry.path.as_str))
def flush_multiple(self): parent = om.Entry('parent', parent=self.root) for key, value in self.data.iteritems(): om.Entry(key, value=value, parent=parent) om.flush(parent) # Read data back from disk and re-build it om.pull(parent) pulled_data = dict() for child in parent: om.pull(child) pulled_data[child.path.basename] = child.value self.assertEquals(self.data, pulled_data)
def test_dict(self): """Write dict""" name = 'mydict.dict' dic = om.Entry(name, parent=self.root) om.flush(dic) om.pull(dic) self.assertEqual(dic.type, 'dict') self.assertEqual(dic.name, 'mydict')
def test_int(self): name = 'integer' value = 10 integer = om.Entry(name, value=value, parent=self.root) om.flush(integer) om.pull(integer) self.assertEquals(integer.value, value) self.assertEquals(integer.name, name) self.assertEquals(integer.type, 'int')
def test_duplicate_entries(self): """An entry exists twice with unique suffixes /root duplicate.int = 5 duplicate.string = "File" """ duplicate = om.Entry('duplicate', parent=self.root) self.assertRaises(om.error.Duplicate, om.pull, duplicate)
def test_pull_unknown_corrupt(self): """Pull from unknown extension and corrupt value Entries are all JSON-formatted. This one however is mis-formatted and will not be successfully parsed. """ entry = om.Entry('unknown_corrupt.abc', parent=self.project) om.pull(entry) self.assertEquals(entry.value, None)
def test_integration(self): """Test a combination of features""" entry = om.Entry('test.string', value="Hello", parent=self.root) child = om.Entry('child.int', value=1, parent=entry) self.assertEquals(entry.type, 'dict') om.flush(entry) self.assertTrue(os.path.exists(entry.path.as_str)) om.pull(entry) self.assertEquals(entry.type, 'dict') entry.value = "Hello" self.assertEquals(entry.type, 'string') self.assertEquals(entry.value, "Hello") om.flush(entry) om.pull(entry) self.assertFalse(os.path.exists(child.path.as_str)) child = om.Entry('child.int', value=1, parent=entry) om.flush(entry) self.assertEquals(om.read(self.root_path, 'test/child'), 1) om.write(self.root_path, '/test/child', 2) self.assertEquals(om.read(self.root_path, 'test/child'), 2) om.write(self.root_path, '/root/test/another', 10) self.assertEquals(om.read(self.root_path, 'root/test/another'), 10)
def test_attributes(self): entry = om.Entry('test_string', value='Hello', parent=self.root) self.assertTrue(entry.type, 'string')
def test_imply_suffix_via_value(self): entry = om.Entry('nosuffix', parent=self.root) entry.value = "Hello" self.assertEquals(entry.type, 'string')
def test_no_suffix(self): entry = om.Entry('test_nosuffix', parent=self.root) self.assertEquals(entry.type, None)
def test_childpath(self): """The path of a child is derived from its basename and parent""" parent = om.Location(self.root_path) entry = om.Entry('test', parent=parent) self.assertEquals(entry.path, parent.path + entry.path.basename)
def test_pull_nonexisting(self): entry = om.Entry('nonexisting', parent=self.project) self.assertRaises(om.error.Exists, om.pull, entry)
def test_pull_unknown(self): """Pull from unknown extension without value""" entry = om.Entry('unknown.abc', parent=self.project) om.pull(entry) self.assertEquals(entry.value, None)
""" import shutil import tempfile import openmetadata as om om.setup_log() # Starting-point root = tempfile.mkdtemp() try: location = om.Location(root) # Add a regular string ostring = om.Entry('simple_data', parent=location) ostring.value = 'my simple string' # Add a list olist = om.Entry('mylist.dict', parent=location) # Containing three datasets.. l1 = om.Entry('item1', value='a string value', parent=olist) l2 = om.Entry('item2', value=True, parent=olist) l3 = om.Entry('item3', value=5, parent=olist) # Add an entry with default value of type `bool` l4 = om.Entry('item4.bool', parent=olist) # ..and a dictionary.. odict = om.Entry('mydict.dict', parent=olist)
def test_suffix_and_type_mismatch(self): height = om.Entry('height.int', value=10.1, parent=self.root) self.assertEquals(height.type, 'float') om.flush(height) om.pull(height) self.assertEquals(height.type, 'float')