Пример #1
0
 def test_premis_element_equality(self):
     premis_agent_1 = premisrw.PREMISAgent(data=c.EX_AGT_1)
     premis_agent_1_copy = premisrw.PREMISAgent(data=c.EX_AGT_1)
     premis_agent_2 = premisrw.PREMISAgent(data=c.EX_AGT_2)
     assert c.EX_AGT_1 != c.EX_AGT_2
     assert premis_agent_1 != premis_agent_2
     assert premis_agent_1 == premis_agent_1_copy
     assert premis_agent_1 == c.EX_AGT_1
     assert c.EX_AGT_1 in [premis_agent_1, premis_agent_1_copy]
Пример #2
0
def get_ss_premis_agents(inst=True):
    """Return PREMIS agents for preservation events performed by the
    Storage Service.
    Note: Archivematica returns a 'repository code'-type agent while we
    are currently just returning a 'preservation system' one. What is
    the desired behaviour here? AM's agents used for compression from
    db::

        +----+-----------------------+----------------------+------------------------------------------------------+--------------------+
        | pk | agentIdentifierType   | agentIdentifierValue | agentName                                            | agentType          |
        +----+-----------------------+----------------------+------------------------------------------------------+--------------------+
        |  1 | preservation system   | Archivematica-1.7    | Archivematica                                        | software           |
        |  2 | repository code       | test                 | test                                                 | organization       |
        +----+-----------------------+----------------------+------------------------------------------------------+--------------------+
    """
    agents = [(
        'agent',
        premisrw.PREMIS_META,
        (
            'agent_identifier',
            ('agent_identifier_type', 'preservation system'),
            ('agent_identifier_value',
                'Archivematica-Storage-Service-{}'.format(ss_version))
        ),
        ('agent_name', 'Archivematica Storage Service'),
        ('agent_type', 'software')
    )]
    if inst:
        return [premisrw.PREMISAgent(data=data) for data in agents]
    return agents
Пример #3
0
    def test_dependency_injection(self):
        """Test the dependency injection (DI) infrastructure for metsrw plugins.

        - client: metsrw.FSEntry
        - services: classes for reading and writing metadata elements, e.g.,
          the PREMISObject class of metsrw.plugins.premisrw or other classes
          exposing the same interface.
        - injector: this test code or the code in metsrw/di.py which calls
          ``provide`` on the ``feature_broker`` singleton.

        The ``FSEntry`` class declares its dependency on the class attributes
        ``premis_object_class``, ``premis_event_class``, and
        ``premis_agent_class`` and further requires that these return classes
        with ``fromtree`` and ``serialize`` methods::

            >>> premis_object_class = Dependency(
            ...     has_methods('serialize'),
            ...     has_class_methods('fromtree'),
            ...     is_class)

        """

        # Clear the feature broker and then register/provide the premisrw
        # plugin classes (services) with the feature broker.
        feature_broker = metsrw.feature_broker
        assert len(feature_broker) == 3
        feature_broker.clear()
        assert not feature_broker
        feature_broker.provide('premis_object_class', premisrw.PREMISObject)
        feature_broker.provide('premis_event_class', premisrw.PREMISEvent)
        feature_broker.provide('premis_agent_class', premisrw.PREMISAgent)
        assert len(feature_broker) == 3

        # Create premisrw instances.
        compression_premis_event = premisrw.PREMISEvent(data=EX_COMPR_EVT)
        premis_events = [compression_premis_event]
        premis_agents = [
            premisrw.PREMISAgent(data=x) for x in [EX_AGT_1, EX_AGT_2]
        ]
        _, compression_program_version, archive_tool = (
            compression_premis_event.compression_details)
        premis_object = premisrw.PREMISObject(
            xsi_type=EX_PTR_XSI_TYPE,
            identifier_value=EX_PTR_IDENTIFIER_VALUE,
            message_digest_algorithm=EX_PTR_MESSAGE_DIGEST_ALGORITHM,
            message_digest=EX_PTR_MESSAGE_DIGEST,
            size=EX_PTR_SIZE,
            format_name=EX_PTR_FORMAT_NAME,
            format_registry_key=EX_PTR_FORMAT_REGISTRY_KEY,
            creating_application_name=archive_tool,
            creating_application_version=compression_program_version,
            date_created_by_application=EX_PTR_DATE_CREATED_BY_APPLICATION)
        transform_files = compression_premis_event.get_decompression_transform_files(
        )

        # Create metsrw ``METSDocument`` and ``FSEntry`` instances.
        mets_doc = metsrw.METSDocument()
        fs_entry = metsrw.FSEntry(path=EX_PTR_PATH,
                                  file_uuid=EX_PTR_IDENTIFIER_VALUE,
                                  use=EX_PTR_PACKAGE_TYPE,
                                  type=EX_PTR_PACKAGE_TYPE,
                                  transform_files=transform_files,
                                  mets_div_type=EX_PTR_AIP_SUBTYPE)
        mets_doc.append_file(fs_entry)

        # Use the ``add_premis_...`` methods to add the PREMIS metadata
        # elements to the ``FSEntry`` instance. This will assert that each
        # PREMIS instance is of the correct type (e.g., that ``premis_object``
        # is an instance of ``FSEntry().premis_object_class``) and will call the
        # instance's ``serialize`` method and incorporate the resulting
        # ``lxml.etree._ElementTree`` instance into the ``FSEntry`` instance
        # appropriately.
        fs_entry.add_premis_object(premis_object)
        for premis_event in premis_events:
            fs_entry.add_premis_event(premis_event)
        for premis_agent in premis_agents:
            fs_entry.add_premis_agent(premis_agent)

        # Assert that the instances returned by the
        # ``FSEntry().get_premis_...`` methods are of the anticipated type.
        new_premis_agents = fs_entry.get_premis_agents()
        for new_premis_agent in new_premis_agents:
            assert isinstance(new_premis_agent, premisrw.PREMISAgent)
            assert new_premis_agent in premis_agents
            assert id(new_premis_agent) not in [id(pa) for pa in premis_agents]
        new_premis_events = fs_entry.get_premis_events()
        for new_premis_event in new_premis_events:
            assert isinstance(new_premis_event, premisrw.PREMISEvent)
            assert new_premis_event in premis_events
            assert id(new_premis_event) not in [id(pa) for pa in premis_events]
        new_premis_objects = fs_entry.get_premis_objects()
        for new_premis_object in new_premis_objects:
            assert isinstance(new_premis_object, premisrw.PREMISObject)
            assert new_premis_object == premis_object
            assert id(new_premis_object) is not premis_object

        # Assert that the resulting mets XML contains a
        # premis:objectIdentifierValue in the anticipated location in the
        # structure with the anticipated value.
        mets_doc_el = mets_doc.serialize()
        xpath = ('mets:amdSec/mets:techMD/mets:mdWrap[@MDTYPE="PREMIS:OBJECT"]'
                 '/mets:xmlData/premis:object/premis:objectIdentifier/'
                 'premis:objectIdentifierValue')
        a = mets_doc_el.find(xpath, namespaces=metsrw.NAMESPACES)
        assert a.text == EX_PTR_IDENTIFIER_VALUE

        # Now change the feature broker so that ``FSEntry``'s dependency on a
        # ``premis_object_class`` class attribute is being fulfilled by a new
        # class: ``BetterPREMISObject``.
        feature_broker.provide('premis_object_class', BetterPREMISObject)

        # Now create a new PREMIS object
        premis_object_tree = premis_object.serialize()
        better_premis_object = BetterPREMISObject.fromtree(premis_object_tree)

        # And re-create the ``METSDocument`` and ``FSEntry`` instances.
        mets_doc = metsrw.METSDocument()
        fs_entry = metsrw.FSEntry(path=EX_PTR_PATH,
                                  file_uuid=EX_PTR_IDENTIFIER_VALUE,
                                  use=EX_PTR_PACKAGE_TYPE,
                                  type=EX_PTR_PACKAGE_TYPE,
                                  transform_files=transform_files,
                                  mets_div_type=EX_PTR_AIP_SUBTYPE)
        mets_doc.append_file(fs_entry)

        # Add the PREMIS metadata again, but this time use the instance of
        # ``BetterPREMISObject``.
        fs_entry.add_premis_object(better_premis_object)
        for premis_event in premis_events:
            fs_entry.add_premis_event(premis_event)
        for premis_agent in premis_agents:
            fs_entry.add_premis_agent(premis_agent)

        # Assert that the instances returned by the
        # ``FSEntry().get_premis_...`` methods are of the anticipated type.
        new_premis_objects = fs_entry.get_premis_objects()
        for new_premis_object in new_premis_objects:
            assert isinstance(new_premis_object, BetterPREMISObject)

        # Make sure we can still find the PREMIS object id value.
        mets_doc_el = mets_doc.serialize()
        assert (mets_doc_el.find(
            xpath,
            namespaces=metsrw.NAMESPACES).text == EX_PTR_IDENTIFIER_VALUE)

        # Reset the feature broker to its default state so subsequent tests
        # don't break.
        metsrw.set_feature_broker_to_default_state(feature_broker)
Пример #4
0
GPG_VERSION = "1.4.16"
SS_VERSION = "0.11.0"
SUCCESS_STATUS = "good times"
DECRYPT_RET_FAIL_STATUS = "bad stuff happened"
RAW_GPG_VERSION = (1, 4, 16)
SOME_FINGERPRINT = EXP_FINGERPRINT = "B9C518917A958DD0B1F5E1B80C3D34DDA5958532"
SOME_OTHER_FINGERPRINT = "BBBB18917A958DD0B1F5E1B80C3D34DDA595BBBB"
TEST_AGENTS = [
    premisrw.PREMISAgent(data=(
        "agent",
        premisrw.PREMIS_META,
        (
            "agent_identifier",
            ("agent_identifier_type", "preservation system"),
            (
                "agent_identifier_value",
                "Archivematica-Storage-Service-{}".format(SS_VERSION),
            ),
        ),
        ("agent_name", "Archivematica Storage Service"),
        ("agent_type", "software"),
    ))
]
BROWSE_FAIL_DICT = {"directories": [], "entries": [], "properties": {}}

FakeGPGRet = namedtuple("FakeGPGRet", "ok status stderr")
ExTarCase = namedtuple("ExTarCase", "path isdir raises expected")
CrTarCase = namedtuple("CrTarCase", "path isfile istar raises expected")
DecryptCase = namedtuple("DecryptCase",
                         "path isfile createsdecryptfile decryptret expected")
EncryptCase = namedtuple("EncryptCase",
from locations.models import gpg, Package, space

GPG_VERSION = '1.4.16'
SS_VERSION = '0.11.0'
SUCCESS_STATUS = 'good times'
DECRYPT_RET_FAIL_STATUS = 'bad stuff happened'
RAW_GPG_VERSION = ('gpg (GnuPG) {}\n'
                   'and some other nonsense\n'
                   'and some more nonsense'.format(GPG_VERSION))
SOME_FINGERPRINT = EXP_FINGERPRINT = 'B9C518917A958DD0B1F5E1B80C3D34DDA5958532'
SOME_OTHER_FINGERPRINT = 'BBBB18917A958DD0B1F5E1B80C3D34DDA595BBBB'
TEST_AGENTS = [
    premisrw.PREMISAgent(
        data=('agent', premisrw.PREMIS_META,
              ('agent_identifier', ('agent_identifier_type',
                                    'preservation system'),
               ('agent_identifier_value',
                'Archivematica-Storage-Service-{}'.format(SS_VERSION))),
              ('agent_name', 'Archivematica Storage Service'), ('agent_type',
                                                                'software')))
]
BROWSE_FAIL_DICT = {'directories': [], 'entries': [], 'properties': {}}

FakeGPGRet = namedtuple('FakeGPGRet', 'ok status stderr')
ExTarCase = namedtuple('ExTarCase', 'path isdir raises expected')
CrTarCase = namedtuple('CrTarCase', 'path isfile istar raises expected')
DecryptCase = namedtuple('DecryptCase',
                         'path isfile createsdecryptfile decryptret expected')
EncryptCase = namedtuple('EncryptCase',
                         'path isdir encrpathisfile encryptret expected')
BrowseCase = namedtuple('BrowseCase', 'path encrpath existsafter expect')
MoveFromCase = namedtuple('MoveFromCase',
Пример #6
0
    def test_dynamic_attrs(self):
        """Tests that dynamic attribute accession works correctly on
        PREMISElement subclasses. This allows us to use the output of the
        ``generate_data`` abstract method to dynamically create accessors for
        PREMIS entities, e.g., ``PREMISObject().identifier_value`` and
        ``PREMISObject().object_identifier_value`` should both return the value
        of the element at 'object_identifier/object_identifier_value' even
        though ``PREMISObject`` does not explicitly define either of those
        attributes.
        """
        compression_event = premisrw.PREMISEvent(data=c.EX_COMPR_EVT)
        _, compression_program_version, archive_tool = (
            compression_event.compression_details)
        inhibitors1 = ('inhibitors', ('inhibitorType', 'GPG'),
                       ('inhibitorTarget', 'All content'))
        premis_object = premisrw.PREMISObject(
            xsi_type=c.EX_PTR_XSI_TYPE,
            identifier_value=c.EX_PTR_IDENTIFIER_VALUE,
            message_digest_algorithm=c.EX_PTR_MESSAGE_DIGEST_ALGORITHM,
            message_digest=c.EX_PTR_MESSAGE_DIGEST,
            size=c.EX_PTR_SIZE,
            format_name=c.EX_PTR_FORMAT_NAME,
            format_registry_key=c.EX_PTR_FORMAT_REGISTRY_KEY,
            creating_application_name=archive_tool,
            creating_application_version=compression_program_version,
            date_created_by_application=c.EX_PTR_DATE_CREATED_BY_APPLICATION,
            inhibitors=[inhibitors1])
        assert premis_object.format_name == c.EX_PTR_FORMAT_NAME
        assert premis_object.identifier_value == c.EX_PTR_IDENTIFIER_VALUE
        assert premis_object.object_identifier_value == c.EX_PTR_IDENTIFIER_VALUE
        assert premis_object.message_digest == c.EX_PTR_MESSAGE_DIGEST
        assert premis_object.object_characteristics__fixity__message_digest == c.EX_PTR_MESSAGE_DIGEST

        # A partial path to a leaf element is not a valid accessor:
        with pytest.raises(AttributeError):
            premis_object.fixity__message_digest

        # XML attribute accessors
        assert premis_object.xsi_type == c.EX_PTR_XSI_TYPE  # namespaced
        assert premis_object.xsi__type == c.EX_PTR_XSI_TYPE  # namespaced
        assert premis_object.type == c.EX_PTR_XSI_TYPE  # not namespaced
        assert premis_object.xsi_schema_location == (
            premisrw.PREMIS_META['xsi:schema_location'])

        assert compression_event.event_type == c.EX_COMPR_EVT_TYPE
        assert compression_event.type == c.EX_COMPR_EVT_TYPE
        assert compression_event.event_detail == c.EX_COMPR_EVT_DETAIL
        assert compression_event.detail == c.EX_COMPR_EVT_DETAIL

        premis_agent_1 = premisrw.PREMISAgent(data=c.EX_AGT_1)
        assert premis_agent_1.name == c.EX_AGT_1_NAME
        assert premis_agent_1.type == c.EX_AGT_1_TYPE
        assert premis_agent_1.identifier_type == c.EX_AGT_1_IDENTIFIER_TYPE
        assert premis_agent_1.identifier_value == c.EX_AGT_1_IDENTIFIER_VALUE
        assert premis_agent_1.agent_name == c.EX_AGT_1_NAME
        assert premis_agent_1.agent_type == c.EX_AGT_1_TYPE
        assert premis_agent_1.agent_identifier_type == c.EX_AGT_1_IDENTIFIER_TYPE
        assert premis_agent_1.agent_identifier_value == c.EX_AGT_1_IDENTIFIER_VALUE
        assert premis_agent_1.agent_identifier__agent_identifier_type == c.EX_AGT_1_IDENTIFIER_TYPE
        with pytest.raises(AttributeError):
            premis_agent_1.agent_identifier__agent_name