Newer
Older
#
# Copyright (C) 2021 Associated Universities, Inc. Washington DC, USA.
#
# This file is part of NRAO Workspaces.
#
# Workspaces is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Workspaces is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Workspaces. If not, see <https://www.gnu.org/licenses/>.
RESTORE_AUXPRODUCTS_NAME,
TEST_RESTORE_METADATA,
get_expected_files_and_dirs_for_restore,
)
from test.conftest import assert_restore_delivered_only_expected_files

Nathan Hertz
committed
from unittest.mock import patch
import pytest

Nathan Hertz
committed
from delivery.context import DeliveryContext
from delivery.delivery import Delivery, main
def verify_extracted_directory(
subdirectory: str,
tar_path: pathlib.Path,
extraction_target: pathlib.Path,
original_data_path: str,
):
"""
Verify that an extracted directory has the same contents as the supplied temporary directory.
Useful for testing tar-related functionality
:param subdirectory: subdirectory to look for inside extraction area
:param tar_path: path to the tarfile to examine
:param extraction_target: location to extract to
:param original_data_path: location of the original files to compare to
:return:
"""
# is it actually a tar?
assert tarfile.is_tarfile(tar_path)
# let's unpack it
shutil.unpack_archive(tar_path, extraction_target / "extracted")
# did it output what we expect?
assert (extraction_target / "extracted" / delivered_subdirectory).exists()
# compare the extracted results with the source
assert_directories_are_same(
extraction_target / "extracted" / delivered_subdirectory, (original_data_path + "/" + subdirectory)
)
def assert_directories_are_same(left, right):
Check that the contents of two directories are the same as far as we care
:param left:
:param right:
compare_dirs = filecmp.dircmp(left, right)
# did the comparison report they are the same
assert len(compare_dirs.left_only) == 0
assert len(compare_dirs.right_only) == 0
assert len(compare_dirs.funny_files) == 0
def test_local_rawdata_no_tar(resource_path_root, tmpdir_factory, capsys):
"""
Test that local delivery works without tar (the simplest case)
"""
temp_directory = str(tmpdir_factory.mktemp("test_basic_rawdata_no_tar"))
test_data_path = resource_path_root / "724126739"
eb_name = "17A-109.sb33151331.eb33786546.57892.65940042824"
main(["-r", "-l", temp_directory, str(test_data_path)])
assert_directories_are_same(
temp_directory + "/17A-109/observation.57892.6594042824/" + eb_name,
test_data_path / "b2f536ca-bdce-4073-b9ee-96d8266109e7" / eb_name,
)
# ensure that we actually got a delivery file with the proper contents
with open("delivery.json", "r") as delivery_results_file:
results = json.load(delivery_results_file)
assert results["delivered_to"] == temp_directory
capsys.readouterr()
def test_local_restore_no_tar(restore_directory: pathlib.Path, tmpdir_factory, capsys):
"""
Test that local delivery works without tar (the simplest case)
"""
temp_directory = str(tmpdir_factory.mktemp("test_basic_restore_no_tar"))
main(["--restore", "-l", temp_directory, str(restore_directory)])
deliver_rel_path_root = (
f"{temp_directory}/{TEST_RESTORE_METADATA.project_code}/{TEST_RESTORE_METADATA.pipeline_spec}"
)
expected_files, expected_dirs_to_file_counts = get_expected_files_and_dirs_for_restore(deliver_rel_path_root)
expected_files.add(pathlib.Path(temp_directory + "/SHA1SUMS"))
expected_files = {pathlib.Path(file).resolve() for file in expected_files}
actual_files = list(p.resolve() for p in pathlib.Path(temp_directory).rglob("*"))
assert_restore_delivered_only_expected_files(actual_files, expected_files, expected_dirs_to_file_counts)
# ensure that we actually got a delivery file with the proper contents
with open("delivery.json", "r") as delivery_results_file:
results = json.load(delivery_results_file)
assert len(results.keys()) == 3
assert results["delivered_to"] == temp_directory
capsys.readouterr()
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def test_local_restore_no_tar_with_flagtemplate(
restore_directory: pathlib.Path, tmp_path_factory: pytest.TempPathFactory, capsys
):
"""
Test that local delivery works without tar (the simplest case)
"""
auxproducts_path = restore_directory.parent / RESTORE_AUXPRODUCTS_NAME
assert auxproducts_path.is_file()
# To avoid possibly polluting the repo,
# use a tmp dir for the restore since the auxproducts tar needs to be copied into it
src_dir = str(tmp_path_factory.mktemp("test_basic_restore_no_tar_flagtemplate_src"))
shutil.copytree(restore_directory, src_dir, dirs_exist_ok=True)
shutil.copy2(auxproducts_path, src_dir + "/products")
dest_dir = str(tmp_path_factory.mktemp("test_basic_restore_no_tar_flagtemplate_dest"))
main(["--restore", "-l", dest_dir, src_dir])
deliver_rel_path_root = f"{dest_dir}/{TEST_RESTORE_METADATA.project_code}/{TEST_RESTORE_METADATA.pipeline_spec}"
expected_files, expected_dirs_to_file_counts = get_expected_files_and_dirs_for_restore(
deliver_rel_path_root, do_include_flagtemplate=True
)
expected_files.add(pathlib.Path(dest_dir + "/SHA1SUMS"))
expected_files = {pathlib.Path(file).resolve() for file in expected_files}
actual_files = list(p.resolve() for p in pathlib.Path(dest_dir).rglob("*"))
assert_restore_delivered_only_expected_files(actual_files, expected_files, expected_dirs_to_file_counts)
# ensure that we actually got a delivery file with the proper contents
with open("delivery.json", "r") as delivery_results_file:
results = json.load(delivery_results_file)
assert len(results.keys()) == 3
assert results["delivered_to"] == dest_dir
capsys.readouterr()
def test_local_rawdata_with_tar(resource_path_root, tmpdir_factory, capsys):
"""
Test that local delivery works with tar
"""
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_basic_rawdata_with_tar"))
test_data_path = resource_path_root / "724126739"
with patch("delivery.destinations.tar.datetime", wraps=datetime.datetime) as dt:
dt.now.return_value = datetime.datetime(2022, 1, 3, 8, 14, 56)
main(["-r", "-t", "-l", str(temp_directory), str(test_data_path)])
eb_name = "17A-109.sb33151331.eb33786546.57892.65940042824"
tar_path = temp_directory / "NRAO_archive_17A-109_20220103-081456.tar"
assert tar_path.exists()
# do we only have it and the SHA1SUMS
assert len(list(temp_directory.iterdir())) == 2
verify_extracted_directory(
"b2f536ca-bdce-4073-b9ee-96d8266109e7/" + eb_name,
"17A-109/observation.57892.6594042824/" + eb_name,
tar_path,
temp_directory,
str(test_data_path) + "/",
)
with open("delivery.json", "r") as delivery_results_file:
results = json.load(delivery_results_file)
assert results["delivered_to"] == str(temp_directory)
capsys.readouterr()
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
def test_local_restore_with_tar(restore_directory: pathlib.Path, tmpdir_factory, capsys):
"""
Test that local restore delivery works with tar
"""
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_basic_restore_with_tar"))
with patch("delivery.destinations.tar.datetime", wraps=datetime.datetime) as dt:
dt.now.return_value = datetime.datetime(2022, 1, 3, 8, 14, 56)
main(["--restore", "-t", "-l", str(temp_directory), str(restore_directory)])
tar_path = temp_directory / f"NRAO_archive_{TEST_RESTORE_METADATA.project_code}_20220103-081456.tar"
# does a tar exist where we think
assert len(list(temp_directory.iterdir())) == 2
assert set(temp_directory.iterdir()) == {tar_path, temp_directory / "SHA1SUMS"}
# Extract the tar and make sure it looks like an untarred, delivered restore
assert tarfile.is_tarfile(tar_path)
extraction_dir = temp_directory / "extracted"
shutil.unpack_archive(tar_path, extraction_dir)
actual_files = list(extraction_dir.rglob("*"))
expected_files, expected_dirs_to_filecounts = get_expected_files_and_dirs_for_restore(
str(extraction_dir / TEST_RESTORE_METADATA.project_code / TEST_RESTORE_METADATA.pipeline_spec)
)
assert_restore_delivered_only_expected_files(actual_files, expected_files, expected_dirs_to_filecounts)
with open("delivery.json", "r") as delivery_results_file:
results = json.load(delivery_results_file)
assert len(results.keys()) == 3
assert results["delivered_to"] == str(temp_directory)
capsys.readouterr()
def test_web_rawdata_no_tar(resource_path_root, tmpdir_factory, capsys):
Test that delivery works to a web destination without tar
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_web_rawdata_no_tar"))
test_data_path = resource_path_root / "724126739"
test_context = DeliveryContext.parse_commandline(["-r", str(test_data_path)])
with patch("delivery.destinations.sharedweb.CapoConfig") as mocked_capo_config:
mocked_capo_config.return_value.settings.return_value.downloadDirectory = str(temp_directory)

Andrew Kapuscinski
committed
mocked_capo_config.return_value.settings.return_value.downloadUrl = "http://testing"
assert str(temp_directory) == mocked_capo_config().settings().downloadDirectory
# check the relationship between the delivery root and the URL
assert str(temp_directory / results["url"].lstrip("http://testing")) == results["delivered_to"]
actual_delivery_dir = pathlib.Path(results["delivered_to"])
assert_directories_are_same(
actual_delivery_dir / "17A-109/observation.57892.6594042824" / eb_name,
test_data_path / "b2f536ca-bdce-4073-b9ee-96d8266109e7" / eb_name,
)
capsys.readouterr()
def test_web_rawdata_no_tmp(resource_path_root, tmpdir_factory, capsys):
"""
Test that delivery works to a web destination and doesn't deliver tmp directories
"""
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_web_rawdata_no_tmp"))
test_data_path = resource_path_root / "724126739_with_tmp"
test_context = DeliveryContext.parse_commandline(["-r", str(test_data_path)])
with patch("delivery.destinations.sharedweb.CapoConfig") as mocked_capo_config:
mocked_capo_config.return_value.settings.return_value.downloadDirectory = str(temp_directory)

Andrew Kapuscinski
committed
mocked_capo_config.return_value.settings.return_value.downloadUrl = "http://testing"
assert str(temp_directory) == mocked_capo_config().settings().downloadDirectory
results = Delivery().deliver(test_context)
# check the relationship between the delivery root and the URL
assert str(temp_directory / results["url"].lstrip("http://testing")) == results["delivered_to"]
actual_delivery_dir = pathlib.Path(results["delivered_to"])
# compare the source and destination
delivered_contents = [d for d in actual_delivery_dir.iterdir()]
test_data_contents = [d for d in test_data_path.iterdir()]
assert test_data_path / "tmp123" in test_data_contents
assert not actual_delivery_dir / "tmp123" in delivered_contents
capsys.readouterr()
def test_web_rawdata_no_tar_with_prefix(resource_path_root, tmpdir_factory, capsys):
"""
Test that delivery works to a web destination without tar
"""
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_web_rawdata_no_tar"))
test_data_path = resource_path_root / "724126739"
eb_name = "17A-109.sb33151331.eb33786546.57892.65940042824"
prefix = "1234"
test_context = DeliveryContext.parse_commandline(["-r", str(test_data_path), "--prefix", prefix])
with patch("delivery.destinations.sharedweb.CapoConfig") as mocked_capo_config:
mocked_capo_config.return_value.settings.return_value.downloadDirectory = str(temp_directory)

Andrew Kapuscinski
committed
mocked_capo_config.return_value.settings.return_value.downloadUrl = "http://testing"
assert str(temp_directory) == mocked_capo_config().settings().downloadDirectory
results = Delivery().deliver(test_context)
# check the relationship between the delivery root and the URL
assert str(temp_directory / results["url"].lstrip("http://testing")) == results["delivered_to"]
actual_delivery_dir = pathlib.Path(results["delivered_to"])
# compare the source and destination
assert_directories_are_same(
actual_delivery_dir / "17A-109/observation.57892.6594042824" / eb_name,
test_data_path / "b2f536ca-bdce-4073-b9ee-96d8266109e7" / eb_name,
)
# make sure that 1234 wound up in the URL and in the delivery directory
assert f"/{prefix}/" in results["url"]
assert f"/{prefix}/" in str(actual_delivery_dir)
capsys.readouterr()
def test_web_rawdata_with_tar(resource_path_root, tmpdir_factory, capsys):
"""
Test that delivery works to a web destination with tar
"""
temp_directory = pathlib.Path(tmpdir_factory.mktemp("test_web_rawdata_with_tar"))
test_data_path = resource_path_root / "724126739"
test_context = DeliveryContext.parse_commandline(["-r", "-t", str(test_data_path)])
with patch("delivery.destinations.sharedweb.CapoConfig") as mocked_capo_config:
mocked_capo_config.return_value.settings.return_value.downloadDirectory = str(temp_directory)

Andrew Kapuscinski
committed
mocked_capo_config.return_value.settings.return_value.downloadUrl = "http://testing"
assert str(temp_directory) == mocked_capo_config().settings().downloadDirectory
with patch("delivery.destinations.tar.datetime", wraps=datetime.datetime) as dt:
dt.now.return_value = datetime.datetime(2022, 1, 3, 8, 14, 56)
results = Delivery().deliver(test_context)
tar_name = "NRAO_archive_17A-109_20220103-081456.tar"
# check the relationship between the delivery root and the URL
assert str(temp_directory / results["url"].lstrip("http://testing")) == results["delivered_to"]
actual_delivery_dir = pathlib.Path(results["delivered_to"])
assert len(list(actual_delivery_dir.iterdir())) == 3
verify_extracted_directory(
"b2f536ca-bdce-4073-b9ee-96d8266109e7/" + eb_name,
"17A-109/observation.57892.6594042824/" + eb_name,
tar_path,
temp_directory,
str(test_data_path),
)
capsys.readouterr()
@pytest.mark.skip()
def test_web_calibration(tmpdir_factory, capsys, resource_path_root):
"""
Tests that delivery can correctly parse a calibration's products and deliver them correctly according to the
new delivery standards for calibrations, found here:
https://open-confluence.nrao.edu/pages/viewpage.action?spaceKey=SPR&title=Delivery+Directory+Improvements
"""
test_context = DeliveryContext.parse_commandline(["-t", str(temp_directory)])
with patch("delivery.destinations.sharedweb.CapoConfig") as mocked_capo_config:
mocked_capo_config.return_value.settings.return_value.downloadDirectory = str(temp_directory)

Andrew Kapuscinski
committed
mocked_capo_config.return_value.settings.return_value.downloadUrl = "http://testing"
assert str(temp_directory) == mocked_capo_config().settings().downloadDirectory
results = Delivery().deliver(test_context)
# TODO: Check that results match the file structure specified in the Confluence page:
# <project-code>
# └── calibration_pipeline.<pipeline-id-1>.<pipeline-id-2>
# |-- <project-code><timestamp>.tar
# └── weblog.tgz
print(results)
capsys.readouterr()