Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix has_packages client script #1854

Merged
merged 1 commit into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/MCPClient/lib/clientScripts/has_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ def already_extracted(f):
# Look for files in a directory that starts with the package name
files = File.objects.filter(
transfer=f.transfer,
currentlocation__startswith=f.currentlocation,
currentlocation__startswith=f.currentlocation.decode(),
removedtime__isnull=True,
).exclude(uuid=f.uuid)
# Check for unpacking events that reference the package
if Event.objects.filter(
file_uuid__in=files,
event_type="unpacking",
event_detail__contains=f.currentlocation,
event_detail__contains=f.currentlocation.decode(),
).exists():
return True
return False
Expand All @@ -49,7 +49,8 @@ def main(job, sip_uuid):
for f in transfer.file_set.filter(removedtime__isnull=True).iterator():
if is_extractable(f) and not already_extracted(f):
job.pyprint(
f.currentlocation, "is extractable and has not yet been extracted."
f.currentlocation.decode(),
"is extractable and has not yet been extracted.",
)
return 0
job.pyprint("No extractable files found.")
Expand Down
129 changes: 129 additions & 0 deletions src/MCPClient/tests/test_has_packages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from pathlib import Path

import has_packages
import pytest
from fpr.models import Format
from fpr.models import FormatGroup
from fpr.models import FormatVersion
from fpr.models import FPCommand
from fpr.models import FPRule
from fpr.models import FPTool
from job import Job
from main.models import Event
from main.models import File
from main.models import FileFormatVersion
from main.models import Transfer


@pytest.fixture
def format_version():
format_group = FormatGroup.objects.create(description="a format group")
format = Format.objects.create(description="a format", group=format_group)

return FormatVersion.objects.create(description="a format 1.0", format=format)


@pytest.fixture
def command():
tool = FPTool.objects.create(description="a tool")

return FPCommand.objects.create(
description="a command",
script_type="pythonScript",
command="script.py",
tool=tool,
)


@pytest.fixture
def extract_fprule(format_version, command):
return FPRule.objects.create(
purpose=FPRule.EXTRACTION, format=format_version, command=command
)


@pytest.fixture
def transfer(tmp_path):
transfer_dir = tmp_path / "transfer"
transfer_dir.mkdir()

return Transfer.objects.create(currentlocation=str(transfer_dir))


@pytest.fixture
def compressed_file(transfer, format_version):
# Simulate a compressed file being extracted to a directory with the same name.
d = Path(transfer.currentlocation) / "compressed.zip"
d.mkdir()

# Place an extracted file in it.
f = d / "file.txt"
f.touch()

# Create File models for the compressed and extracted files.
result = File.objects.create(
transfer=transfer, originallocation=bytes(d), currentlocation=bytes(d)
)
File.objects.create(
transfer=transfer, originallocation=bytes(f), currentlocation=bytes(f)
)

# Create a file format version for the compressed file.
FileFormatVersion.objects.create(file_uuid=result, format_version=format_version)

return result


@pytest.mark.django_db
@pytest.mark.parametrize(
"rule_purpose,expected_exit_code",
[(FPRule.EXTRACTION, 0), (FPRule.CHARACTERIZATION, 1)],
ids=["extract_rule", "not_extract_rule"],
)
def test_main_detects_file_is_extractable_based_on_extract_fpr_rule(
mocker,
transfer,
compressed_file,
format_version,
command,
rule_purpose,
expected_exit_code,
):
job = mocker.Mock(spec=Job)
FPRule.objects.create(purpose=rule_purpose, format=format_version, command=command)

result = has_packages.main(job, str(transfer.uuid))

assert result == expected_exit_code


@pytest.mark.django_db
@pytest.mark.parametrize(
"event_type,expected_exit_code",
[("unpacking", 1), ("charaterization", 0)],
ids=["unpacking_event", "not_unpacking_event"],
)
def test_main_detects_file_was_already_extracted_from_unpacking_event(
mocker,
transfer,
compressed_file,
format_version,
command,
extract_fprule,
event_type,
expected_exit_code,
):
job = mocker.Mock(spec=Job)
extracted_file = File.objects.get(
currentlocation__startswith=compressed_file.currentlocation.decode(),
currentlocation__endswith="file.txt",
)
Event.objects.create(
file_uuid=extracted_file,
event_type=event_type,
event_detail=f"Unpacked from: {extracted_file.currentlocation} ({compressed_file.uuid})",
)

result = has_packages.main(job, str(transfer.uuid))

assert result == expected_exit_code