Skip to content

Commit

Permalink
Merge pull request #89 from metno/issue87_file_archive_delete_fix
Browse files Browse the repository at this point in the history
Issue87 file archive delete fix
  • Loading branch information
mortenwh authored May 5, 2022
2 parents eaa1ffd + 0b16023 commit 364d87f
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 36 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ python dmci_start_api.py
Then you can post with curl to the api - endpoint:

```bash
curl --data-binary "@<PATH_TO_MMD_FILE>" localhost:5000/v1/insert
# Validate, insert, create and update call signature
curl --data-binary "@<PATH_TO_MMD_FILE>" localhost:5000/v1/validate
# Delete works differently
curl -X POST localhost:5000/v1/delete/<UUID_OF_FILE_TO_DELETE>

```
insert is currently the only implemented command. Other commands will return 404 Not Found until implementation.
Available commands are: validate, insert or create, update, and delete. Note that insert and create is the same - insert will be removed in the next major version (1.0).

The API uses HTTP return codes, and expected returns are:

Expand Down
1 change: 1 addition & 0 deletions dmci/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __init__(self):
sys.exit(1)

# Set up api entry points
@self.route("/v1/create", methods=["POST"])
@self.route("/v1/insert", methods=["POST"])
def post_insert():
msg, code = self._insert_update_method_post("insert", request)
Expand Down
4 changes: 1 addition & 3 deletions dmci/api/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,11 @@ def distribute(self):
if dist not in self.CALL_MAP:
skipped.append(dist)
continue

obj = self.CALL_MAP[dist](
self._dist_cmd,
xml_file=self._dist_xml_file,
metadata_id=self._dist_metadata_id,
worker=self,
**self._kwargs
worker=self
)
valid &= obj.is_valid()
if obj.is_valid():
Expand Down
5 changes: 3 additions & 2 deletions dmci/distributors/distributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"""

import os
import uuid
import logging

from enum import Enum
Expand Down Expand Up @@ -69,11 +70,11 @@ def __init__(self, cmd, xml_file=None, metadata_id=None, worker=None, **kwargs):
return

if metadata_id is not None:
if isinstance(metadata_id, str) and metadata_id:
if isinstance(metadata_id, uuid.UUID) and metadata_id:
self._metadata_id = metadata_id
self._valid = True
else:
logger.error("Metadata identifier must be a non-empty string")
logger.error("Metadata identifier must be a valid UUID")
self._valid = False
return

Expand Down
2 changes: 1 addition & 1 deletion dmci/distributors/file_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def _add_to_archive(self):

def _delete_from_archive(self):
"""Delete a file from the archive."""
fileUUID = self._worker._file_metadata_id
fileUUID = self._metadata_id
if not isinstance(fileUUID, uuid.UUID):
msg = "No valid metadata_identifier provided, cannot delete file"
logger.error(msg)
Expand Down
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import os
import sys
import uuid
import shutil
import pytest

Expand Down Expand Up @@ -104,3 +105,8 @@ def tmpConf(monkeypatch):
theConf.readConfig(confFile)
monkeypatch.setattr("dmci.CONFIG", theConf)
return theConf


@pytest.fixture(scope="function")
def tmpUUID():
return uuid.uuid4()
21 changes: 11 additions & 10 deletions tests/test_dist/test_distributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@


@pytest.mark.dist
def testDistDistributor_Init(mockXml):
def testDistDistributor_Init(mockXml, tmpUUID):
"""Test the Distributor super class init."""

# Check Insert Command
assert Distributor("insert", metadata_id="some_id").is_valid() is False
assert Distributor("insert", metadata_id=tmpUUID).is_valid() is False
assert Distributor("insert", xml_file="/path/to/nowhere").is_valid() is False
assert Distributor("insert", xml_file=mockXml).is_valid() is True
assert Distributor("inSeRt", xml_file=mockXml).is_valid() is True
assert Distributor("insert", xml_file=mockXml, metadata_id="stuff").is_valid() is False

# Check Update Command
assert Distributor("update", metadata_id="some_id").is_valid() is False
assert Distributor("update", metadata_id=tmpUUID).is_valid() is False
assert Distributor("update", xml_file="/path/to/nowhere").is_valid() is False
assert Distributor("update", xml_file=mockXml).is_valid() is True
assert Distributor("uPdatE", xml_file=mockXml).is_valid() is True
Expand All @@ -43,27 +44,27 @@ def testDistDistributor_Init(mockXml):
assert Distributor("delete", xml_file=mockXml).is_valid() is False
assert Distributor("delete", metadata_id=None).is_valid() is False
assert Distributor("delete", metadata_id=1234).is_valid() is False
assert Distributor("delete", metadata_id="some_id").is_valid() is True
assert Distributor("deLEte", metadata_id="some_id").is_valid() is True
assert Distributor("delete", xml_file=mockXml, metadata_id="some_id").is_valid() is False
assert Distributor("delete", metadata_id=tmpUUID).is_valid() is True
assert Distributor("deLEte", metadata_id=tmpUUID).is_valid() is True
assert Distributor("delete", xml_file=mockXml, metadata_id=tmpUUID).is_valid() is False

# Check Unsupported Command
assert Distributor("blabla", metadata_id="some_id").is_valid() is False
assert Distributor("blabla", metadata_id=tmpUUID).is_valid() is False
assert Distributor("blabla", xml_file=mockXml).is_valid() is False
assert Distributor(12345678, metadata_id="some_id").is_valid() is False
assert Distributor(12345678, metadata_id=tmpUUID).is_valid() is False
assert Distributor(12345678, xml_file=mockXml).is_valid() is False

# END Test testDistDistributor_Init


@pytest.mark.dist
def testDistDistributor_Run():
def testDistDistributor_Run(tmpUUID):
"""Test the Distributor super class run function.
Calling run() on the superclass should raise an error as this
function must be implemented in subclasses.
"""
with pytest.raises(NotImplementedError):
Distributor("insert", metadata_id="some_id").run()
Distributor("insert", metadata_id=tmpUUID).run()

# END Test testDistDistributor_Run
15 changes: 8 additions & 7 deletions tests/test_dist/test_file_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@


@pytest.mark.dist
def testDistFile_Init():
def testDistFile_Init(tmpUUID):
"""Test the FileDist class init."""
# Check that it initialises properly by running some of the simple
# Distributor class tests
assert FileDist("insert", metadata_id="some_id").is_valid() is False
assert FileDist("update", metadata_id="some_id").is_valid() is False
assert FileDist("delete", metadata_id="some_id").is_valid() is True
assert FileDist("blabla", metadata_id="some_id").is_valid() is False
assert FileDist("insert", metadata_id=tmpUUID).is_valid() is False
assert FileDist("update", metadata_id=tmpUUID).is_valid() is False
assert FileDist("delete", metadata_id=tmpUUID).is_valid() is True
assert FileDist("blabla", metadata_id=tmpUUID).is_valid() is False

# END Test testDistFile_Init

Expand Down Expand Up @@ -179,13 +179,14 @@ def testDistFile_Delete(tmpDir, filesDir, monkeypatch):
# Try to delete with no identifier set
tstDist._cmd = DistCmd.DELETE
goodUUID = tstWorker._file_metadata_id
tstWorker._file_metadata_id = "123456789abcdefghijkl"

tstWorker._metadata_id = "123456789abcdefghijkl"
assert tstDist.run() == (
False, "No valid metadata_identifier provided, cannot delete file"
)

# Set the identifier and try to delete again, but fail on unlink
tstWorker._file_metadata_id = goodUUID
tstDist._metadata_id = goodUUID
with monkeypatch.context() as mp:
mp.setattr("os.unlink", causeOSError)
assert tstDist.run() == (
Expand Down
22 changes: 11 additions & 11 deletions tests/test_dist/test_pycsw_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@


@pytest.mark.dist
def testDistPyCSW_Init():
def testDistPyCSW_Init(tmpUUID):
"""Test the PyCSWDist class init."""
# Check that it initialises properly by running some of the simple
# Distributor class tests
assert PyCSWDist("insert", metadata_id="some_id").is_valid() is False
assert PyCSWDist("update", metadata_id="some_id").is_valid() is False
assert PyCSWDist("delete", metadata_id="some_id").is_valid() is True
assert PyCSWDist("blabla", metadata_id="some_id").is_valid() is False
assert PyCSWDist("insert", metadata_id=tmpUUID).is_valid() is False
assert PyCSWDist("update", metadata_id=tmpUUID).is_valid() is False
assert PyCSWDist("delete", metadata_id=tmpUUID).is_valid() is True
assert PyCSWDist("blabla", metadata_id=tmpUUID).is_valid() is False

# END Test testDistPyCSW_Init


@pytest.mark.dist
def testDistPyCSW_Run():
def testDistPyCSW_Run(tmpUUID):
"""Test the run command with invalid parameters."""
# WRONG command test
assert PyCSWDist("blabla", metadata_id="some_id").run() == (False, "The run job is invalid")
assert PyCSWDist("insert", metadata_id="some_id").run() == (False, "The run job is invalid")
assert PyCSWDist("blabla", metadata_id=tmpUUID).run() == (False, "The run job is invalid")
assert PyCSWDist("insert", metadata_id=tmpUUID).run() == (False, "The run job is invalid")

# END Test testDistPyCSW_Run

Expand Down Expand Up @@ -120,7 +120,7 @@ class mockResp:


@pytest.mark.dist
def testDistPyCSW_Delete(monkeypatch, mockXml):
def testDistPyCSW_Delete(monkeypatch, mockXml, tmpUUID):
"""Test delete commands via run()."""
class mockResp:
text = "Mock response"
Expand All @@ -135,15 +135,15 @@ class mockResp:
"dmci.distributors.pycsw_dist.requests.post", lambda *a, **k: mockResp
)
mp.setattr(PyCSWDist, "_get_transaction_status", lambda *a: True)
assert PyCSWDist("delete", metadata_id="some_id").run() == (True, "Mock response")
assert PyCSWDist("delete", metadata_id=tmpUUID).run() == (True, "Mock response")

# delete returns false
with monkeypatch.context() as mp:
mp.setattr(
"dmci.distributors.pycsw_dist.requests.post", lambda *a, **k: mockResp
)
mp.setattr(PyCSWDist, "_get_transaction_status", lambda *a: False)
assert PyCSWDist("delete", metadata_id="some_id").run() == (False, "Mock response")
assert PyCSWDist("delete", metadata_id=tmpUUID).run() == (False, "Mock response")

# END Test testDistPyCSW_Delete

Expand Down

0 comments on commit 364d87f

Please sign in to comment.