Example #1
0
 def decode_parsed(self, json_as_dict: dict) -> IrodsMetadata:
     if not isinstance(json_as_dict, List):
         return super().decode(json_as_dict)
     irods_metadata = IrodsMetadata()
     for item in json_as_dict:
         assert isinstance(item, dict)
         attribute = item[BATON_AVU_ATTRIBUTE_PROPERTY]
         value = item[BATON_AVU_VALUE_PROPERTY]
         irods_metadata.add(attribute, value)
     return irods_metadata
def combine_metadata(metadata_collection: Iterable[IrodsMetadata]) -> IrodsMetadata:
    """
    Combines n metadata objects into a single metadata object. Key values are merged, duplicate values are removed.
    :param metadata_collection: the collection of metadata to combine
    :return: the combined metadata
    """
    combined = IrodsMetadata()
    for metadata in metadata_collection:
        for key, values in metadata.items():
            for value in values:
                combined.add(key, value)
    return combined
 def setUp(self):
     self.test_with_baton = TestWithBaton(baton_setup=BATON_SETUP)
     self.test_with_baton.setup()
     self.setup_helper = SetupHelper(self.test_with_baton.icommands_location)
     self.mapper = self.create_mapper()
     self.metadata = IrodsMetadata({"key_1": {"value_1", "value_2"}, "key_2": {"value_3"}})
     self._entity = None
     self._entities = None
Example #4
0
 def default(self, irods_metadata: IrodsMetadata) -> PrimitiveJsonSerializableType:
     if not isinstance(irods_metadata, IrodsMetadata):
         return super().default(irods_metadata)
     avus = []
     for key, values in irods_metadata.items():
         for value in values:
             avus.append({
                 BATON_AVU_ATTRIBUTE_PROPERTY: key,
                 BATON_AVU_VALUE_PROPERTY: value
             })
     return avus
class TestIrodsMetadata(unittest.TestCase):
    """
    Tests for `IrodsMetadata`.
    """

    def setUp(self):
        self.metadata = IrodsMetadata({"attribute_a": {"value_1"}, "attribute_b": {"value_b"}})

    def test_equal(self):
        self.assertEqual(copy.deepcopy(self.metadata), self.metadata)

    def test_add_when_key_does_not_exists(self):
        self.metadata.add("key", "value")
        self.assertEqual(self.metadata["key"], {"value"})

    def test_add_when_key_exists(self):
        self.metadata["key"] = {"value_1"}
        self.metadata.add("key", "value_2")
        self.assertEqual(self.metadata["key"], {"value_1", "value_2"})

    def test_get_when_default(self):
        default = object()
        value = self.metadata.get("not_set", default=default)
        self.assertEqual(value, default)
 def setUp(self):
     self.metadata = IrodsMetadata({"attribute_a": {"value_1"}, "attribute_b": {"value_b"}})
 def setUp(self):
     self.path = "/path"
     self.data_object = DataObject(self.path,
                                   metadata=IrodsMetadata(),
                                   replicas={})
class _TestBatonIrodsEntityMetadataMapper(unittest.TestCase):
    """
    Tests for `_BatonIrodsMetadataMapper`.
    """
    @abstractmethod
    def create_mapper(self) -> _BatonIrodsMetadataMapper:
        """
        Creates a mapper to test with.
        :return: the created mapper
        """

    @abstractmethod
    def create_irods_entity(self, name: str, metadata: IrodsMetadata=IrodsMetadata()) -> IrodsEntity:
        """
        Creates an iRODS entity to test with
        :param name: the name of the entity to create
        :param metadata: the metadata to give to the entity
        :return: the created entity
        """

    def setUp(self):
        self.test_with_baton = TestWithBaton(baton_setup=BATON_SETUP)
        self.test_with_baton.setup()
        self.setup_helper = SetupHelper(self.test_with_baton.icommands_location)
        self.mapper = self.create_mapper()
        self.metadata = IrodsMetadata({"key_1": {"value_1", "value_2"}, "key_2": {"value_3"}})
        self._entity = None
        self._entities = None

    def tearDown(self):
        self.test_with_baton.tear_down()

    @property
    def entity(self) -> IrodsEntity:
        """
        Lazily creates the test entity (prevents spending time creating unused entities in iRODS).
        :return: an example entity
        """
        if self._entity is None:
            self._entity = self.create_irods_entity("%s_entity" % NAMES[0])
        return self._entity

    @property
    def entities(self) -> List[IrodsEntity]:
        """
        Lazily creates a set of test entities (prevents spending time creating unused entities in iRODS).
        :return: an example collection of entities
        """
        if self._entities is None:
            self._entities = [self.create_irods_entity(name) for name in NAMES]
        return self._entities

    def test_get_all_with_no_paths(self):
        self.assertEqual(self.mapper.get_all([]), [])

    def test_get_all_with_single_path_that_is_invalid(self):
        self.assertRaises(FileNotFoundError, self.mapper.get_all, "/invalid")

    def test_get_all_with_single_path(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        self.assertEqual(self.mapper.get_all(entity.path), self.metadata)

    def test_get_all_with_multiple_paths_including_an_invalid_path(self):
        self.assertRaises(FileNotFoundError, self.mapper.get_all, [self.entity.path, "/invalid"])

    def test_get_all_with_multiple_paths(self):
        entities = [self.create_irods_entity(name, self.metadata) for name in NAMES]
        paths = [entity.path for entity in entities]
        self.assertEqual(self.mapper.get_all(paths), [entity.metadata for entity in entities])

    def test_add_with_single_path_that_is_invalid(self):
        self.assertRaises(FileNotFoundError, self.mapper.add, "/invalid", self.metadata)

    def test_add_with_single_path(self):
        self.mapper.add(self.entity.path, self.metadata)
        self.assertEqual(self.mapper.get_all(self.entity.path), self.metadata)

    def test_add_with_multiple_paths_including_an_invalid_path(self):
        self.assertRaises(FileNotFoundError, self.mapper.add, [self.entity.path, "/invalid"], self.metadata)

    def test_add_with_multiple_paths_but_invalid_number_of_associated_metadata(self):
        paths = [entity.path for entity in self.entities]
        assert len(paths) > 2
        self.assertRaises(ValueError, self.mapper.add, paths, [self.metadata, self.metadata])

    def test_add_with_multiple_paths_and_single_metadata(self):
        paths = [entity.path for entity in self.entities]
        self.mapper.add(paths, self.metadata)
        self.assertEqual(self.mapper.get_all(paths), [self.metadata for _ in self.entities])

    def test_add_with_multiple_paths_and_multiple_metadata(self):
        paths = [entity.path for entity in self.entities]
        metadata = [self.metadata for _ in range(len(self.entities))]
        self.mapper.add(paths, metadata)
        self.assertEqual(self.mapper.get_all(paths), metadata)

    def test_add_no_metadata(self):
        self.mapper.add(self.entity.path, IrodsMetadata())
        self.assertEqual(self.mapper.get_all(self.entity.path), IrodsMetadata())

    def test_add_metadata_with_same_key(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        del self.metadata["key_1"]
        assert len(self.metadata) == 1
        self.assertRaises(KeyError, self.mapper.add, entity.path, self.metadata)

    def test_add_adds_metadata(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        additional_metadata = IrodsMetadata({"other": {"values"}})
        self.mapper.add(entity.path, additional_metadata)
        self.assertEqual(self.mapper.get_all(entity.path),
                         IrodsMetadata({**dict(entity.metadata), **dict(additional_metadata)}))

    def test_add_appends_if_key_exists_and_not_same_value(self):
        values = ["value_1", "value_2"]
        key = "key"
        entity = self.create_irods_entity(NAMES[0], IrodsMetadata({key: {values[0]}}))
        self.mapper.add(entity.path, IrodsMetadata({key: {values[1]}}))
        self.assertEqual(IrodsMetadata({key: {values[0], values[1]}}), self.mapper.get_all(entity.path))

    def test_set_with_no_paths(self):
        self.mapper.set([], self.metadata)

    def test_set_with_single_path_that_is_invalid(self):
        self.assertRaises(FileNotFoundError, self.mapper.set, "/invalid", self.metadata)

    def test_set_with_single_path(self):
        self.mapper.set(self.entity.path, self.metadata)
        self.assertEqual(self.mapper.get_all(self.entity.path), self.metadata)

    def test_set_with_multiple_paths_including_an_invalid_path(self):
        self.assertRaises(FileNotFoundError, self.mapper.set, [self.entity.path, "/invalid"], self.metadata)

    def test_set_with_multiple_paths_and_single_metadata(self):
        paths = [entity.path for entity in self.entities]
        self.mapper.set(paths, self.metadata)
        self.assertEqual(self.mapper.get_all(paths), [self.metadata for _ in self.entities])

    def test_set_with_multiple_paths_and_multiple_metadata(self):
        paths = [entity.path for entity in self.entities]
        metadata = [self.metadata for _ in range(len(self.entities))]
        self.mapper.set(paths, metadata)
        self.assertEqual(self.mapper.get_all(paths), metadata)

    def test_set_overrides_existing_metadata(self):
        overriden_key = list(self.metadata.keys())[0]
        value = {"new_value"}
        entity_1 = self.create_irods_entity(NAMES[0], self.metadata)
        del self.metadata[overriden_key]
        entity_2 = self.create_irods_entity(NAMES[1], self.metadata)
        self.mapper.set([entity_1.path, entity_2.path], IrodsMetadata({overriden_key: value}))
        self.metadata[overriden_key] = value
        self.assertEqual(self.mapper.get_all(entity_1.path), self.metadata)
        self.assertEqual(self.mapper.get_all(entity_2.path), self.metadata)

    def test_remove_with_no_paths(self):
        self.mapper.remove([], self.metadata)

    def test_remove_with_single_path_that_is_invalid(self):
        self.assertRaises(FileNotFoundError, self.mapper.remove, "/invalid", self.metadata)

    def test_remove_with_single_path(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        self.mapper.remove(entity.path, self.metadata)
        self.assertEqual(self.mapper.get_all(entity.path), IrodsMetadata())

    def test_remove_with_multiple_paths_including_an_invalid_path(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        self.assertRaises(FileNotFoundError, self.mapper.remove, [entity.path, "/invalid"], self.metadata)

    def test_remove_with_multiple_paths_and_single_metadata(self):
        entities = [self.create_irods_entity(name, self.metadata) for name in NAMES]
        paths = [entity.path for entity in entities]
        self.mapper.remove(paths, self.metadata)
        self.assertEqual(self.mapper.get_all(paths), [IrodsMetadata() for _ in paths])

    def test_remove_with_multiple_paths_and_multiple_metadata(self):
        entities = [self.create_irods_entity(name, self.metadata) for name in NAMES]
        paths = [entity.path for entity in entities]
        metadata = [entity.metadata for entity in entities]
        self.mapper.remove(paths, metadata)
        self.assertEqual(self.mapper.get_all(paths), [IrodsMetadata() for _ in paths])

    def test_remove_unset_metadata(self):
        self.assertRaises(KeyError, self.mapper.remove, self.entity.path, self.metadata)

    def test_remove_partially_unset_metadata(self):
        partial_metadata = deepcopy(self.metadata)
        del partial_metadata["key_1"]
        entity = self.create_irods_entity(NAMES[0], partial_metadata)
        self.assertRaises(KeyError, self.mapper.remove, entity.path, self.metadata)

    def test_remove_subset_of_metadata(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        assert len(self.metadata) == 2
        partial_metadata_1 = deepcopy(self.metadata)
        del partial_metadata_1["key_1"]
        partial_metadata_2 = deepcopy(self.metadata)
        del partial_metadata_2["key_2"]
        self.mapper.remove(entity.path, partial_metadata_1)
        self.assertEqual(self.mapper.get_all(entity.path), partial_metadata_2)

    def test_remove_all_with_no_paths(self):
        self.mapper.remove_all([])

    def test_remove_all_with_single_path_that_is_invalid(self):
        self.assertRaises(FileNotFoundError, self.mapper.remove_all, "/invalid")

    def test_remove_all_with_single_path(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        self.mapper.remove_all(entity.path)
        self.assertEqual(self.mapper.get_all(entity.path), IrodsMetadata())

    def test_remove_all_with_multiple_paths_including_an_invalid_path(self):
        entity = self.create_irods_entity(NAMES[0], self.metadata)
        self.assertRaises(FileNotFoundError, self.mapper.remove_all, [entity.path, "/invalid"])

    def test_remove_all_with_multiple_paths(self):
        entities = [self.create_irods_entity(name, self.metadata) for name in NAMES]
        paths = [entity.path for entity in entities]
        self.mapper.remove_all(paths)
        self.assertEqual(self.mapper.get_all(paths), [IrodsMetadata() for _ in range(len(entities))])