From 6f23f805fe708262117d0fcda29ee9ac09a03c7d Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 2 Oct 2023 16:23:05 +0000 Subject: [PATCH] Fix has_packages client script --- .../lib/clientScripts/has_packages.py | 7 +- src/MCPClient/tests/test_has_packages.py | 129 ++++++++++++++++++ 2 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/MCPClient/tests/test_has_packages.py diff --git a/src/MCPClient/lib/clientScripts/has_packages.py b/src/MCPClient/lib/clientScripts/has_packages.py index 0532f5be00..67709383bf 100755 --- a/src/MCPClient/lib/clientScripts/has_packages.py +++ b/src/MCPClient/lib/clientScripts/has_packages.py @@ -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 @@ -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.") diff --git a/src/MCPClient/tests/test_has_packages.py b/src/MCPClient/tests/test_has_packages.py new file mode 100644 index 0000000000..02b5c46fa5 --- /dev/null +++ b/src/MCPClient/tests/test_has_packages.py @@ -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