|
| 1 | +import json |
| 2 | +import os |
| 3 | +import shutil |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +import pytest |
| 7 | + |
| 8 | +from job_executor.adapter.fs import LocalStorageAdapter |
| 9 | +from job_executor.adapter.fs.models.datastore_versions import ( |
| 10 | + DatastoreVersions, |
| 11 | + DraftVersion, |
| 12 | +) |
| 13 | +from job_executor.adapter.fs.models.metadata import ( |
| 14 | + MetadataAll, |
| 15 | +) |
| 16 | +from job_executor.common.exceptions import LocalStorageError |
| 17 | + |
| 18 | +DATASTORE_DIR = "tests/unit/resources/adapter/local_storage/TEST_DATASTORE" |
| 19 | +WORKING_DIR = DATASTORE_DIR + "_working" |
| 20 | +DATASTORE_DATA_DIR = f"{DATASTORE_DIR}/data" |
| 21 | + |
| 22 | +local_storage = LocalStorageAdapter(Path(DATASTORE_DIR)) |
| 23 | + |
| 24 | +DATASTORE_VERSIONS_PATH = f"{DATASTORE_DIR}/datastore/datastore_versions.json" |
| 25 | +DRAFT_METADATA_ALL_PATH = f"{DATASTORE_DIR}/datastore/metadata_all__draft.json" |
| 26 | +DRAFT_VERSION_PATH = f"{DATASTORE_DIR}/datastore/draft_version.json" |
| 27 | +DATA_VERSIONS_PATH = f"{DATASTORE_DIR}/datastore/data_versions__1_0.json" |
| 28 | +METADATA_ALL_PATH = f"{DATASTORE_DIR}/datastore/metadata_all__1_0_0.json" |
| 29 | + |
| 30 | +DRAFT_DATASET_NAME = "UTDANNING" |
| 31 | +DRAFT_DATA_PATH = f"{DATASTORE_DATA_DIR}/UTDANNING/UTDANNING__DRAFT.parquet" |
| 32 | + |
| 33 | +DRAFT2_DATASET_NAME = "BRUTTO_INNTEKT" |
| 34 | +RELEASED_DRAFT2_DATA_PATH = ( |
| 35 | + f"{DATASTORE_DATA_DIR}/BRUTTO_INNTEKT/BRUTTO_INNTEKT__1_1" |
| 36 | +) |
| 37 | + |
| 38 | +WORKING_DIR_DATASET = "FOEDESTED" |
| 39 | +MOVED_WORKING_DIR_DATASET_DATA_PATH = ( |
| 40 | + f"{DATASTORE_DATA_DIR}/FOEDESTED/FOEDESTED__DRAFT.parquet" |
| 41 | +) |
| 42 | + |
| 43 | + |
| 44 | +def setup_function(): |
| 45 | + if os.path.isdir("tests/unit/resources_backup"): |
| 46 | + shutil.rmtree("tests/unit/resources_backup") |
| 47 | + shutil.copytree("tests/unit/resources", "tests/unit/resources_backup") |
| 48 | + |
| 49 | + |
| 50 | +def teardown_function(): |
| 51 | + shutil.rmtree("tests/unit/resources") |
| 52 | + shutil.move("tests/unit/resources_backup", "tests/unit/resources") |
| 53 | + |
| 54 | + |
| 55 | +def read_json(file_path: str) -> dict: |
| 56 | + with open(file_path, encoding="utf-8") as f: |
| 57 | + return json.load(f) |
| 58 | + |
| 59 | + |
| 60 | +def test_make_dataset_dir(): |
| 61 | + local_storage.datastore_dir.make_dataset_dir(WORKING_DIR_DATASET) |
| 62 | + assert os.path.isdir(f"{DATASTORE_DATA_DIR}/{WORKING_DIR_DATASET}") |
| 63 | + |
| 64 | + |
| 65 | +def test_get_data_versions(): |
| 66 | + assert local_storage.datastore_dir.get_data_versions("1_0_0") == read_json( |
| 67 | + DATA_VERSIONS_PATH |
| 68 | + ) |
| 69 | + |
| 70 | + |
| 71 | +def test_write_data_versions(): |
| 72 | + local_storage.datastore_dir.write_data_versions({}, "1_0_0") |
| 73 | + assert read_json(DATA_VERSIONS_PATH) == {} |
| 74 | + |
| 75 | + |
| 76 | +def test_get_draft_version(): |
| 77 | + assert isinstance( |
| 78 | + local_storage.datastore_dir.get_draft_version(), DraftVersion |
| 79 | + ) |
| 80 | + |
| 81 | + |
| 82 | +def test_write_draft_version(): |
| 83 | + draft_version = local_storage.datastore_dir.get_draft_version() |
| 84 | + draft_version.description = "updated" |
| 85 | + local_storage.datastore_dir.write_draft_version(draft_version) |
| 86 | + assert ( |
| 87 | + local_storage.datastore_dir.get_draft_version().description == "updated" |
| 88 | + ) |
| 89 | + |
| 90 | + |
| 91 | +def test_get_datastore_versions(): |
| 92 | + assert isinstance( |
| 93 | + local_storage.datastore_dir.get_datastore_versions(), DatastoreVersions |
| 94 | + ) |
| 95 | + |
| 96 | + |
| 97 | +def test_write_datastore_versions(): |
| 98 | + datastore_versions = local_storage.datastore_dir.get_datastore_versions() |
| 99 | + datastore_versions.description = "updated" |
| 100 | + local_storage.datastore_dir.write_datastore_versions(datastore_versions) |
| 101 | + assert ( |
| 102 | + local_storage.datastore_dir.get_datastore_versions().description |
| 103 | + == "updated" |
| 104 | + ) |
| 105 | + |
| 106 | + |
| 107 | +def test_get_metadata_all(): |
| 108 | + assert isinstance( |
| 109 | + local_storage.datastore_dir.get_metadata_all("1_0_0"), MetadataAll |
| 110 | + ) |
| 111 | + |
| 112 | + |
| 113 | +def test_write_metadata_all(): |
| 114 | + metadata_all = local_storage.datastore_dir.get_metadata_all("1_0_0") |
| 115 | + metadata_all.data_structures = [] |
| 116 | + local_storage.datastore_dir.write_metadata_all(metadata_all, "1_0_0") |
| 117 | + assert ( |
| 118 | + local_storage.datastore_dir.get_metadata_all("1_0_0").data_structures |
| 119 | + == [] |
| 120 | + ) |
| 121 | + |
| 122 | + |
| 123 | +def delete_parquet_draft(): |
| 124 | + local_storage.datastore_dir.delete_parquet_draft(DRAFT_DATASET_NAME) |
| 125 | + assert not os.path.isfile(DRAFT_DATA_PATH) |
| 126 | + |
| 127 | + |
| 128 | +def test_rename_parquet_draft_to_release(): |
| 129 | + release_path = local_storage.datastore_dir.rename_parquet_draft_to_release( |
| 130 | + DRAFT2_DATASET_NAME, "1_1_0" |
| 131 | + ) |
| 132 | + assert os.path.isdir(RELEASED_DRAFT2_DATA_PATH) |
| 133 | + assert release_path == f"{DRAFT2_DATASET_NAME}__1_1" |
| 134 | + |
| 135 | + |
| 136 | +def test_move_working_dir_parquet_to_datastore(): |
| 137 | + local_storage.datastore_dir.make_dataset_dir(WORKING_DIR_DATASET) |
| 138 | + local_storage.move_working_dir_parquet_to_datastore(WORKING_DIR_DATASET) |
| 139 | + assert os.path.isfile(MOVED_WORKING_DIR_DATASET_DATA_PATH) |
| 140 | + |
| 141 | + |
| 142 | +def test_make_temp_directory(): |
| 143 | + datastore_content = os.listdir(Path(DATASTORE_DIR) / "datastore") |
| 144 | + local_storage.datastore_dir.save_temporary_backup() |
| 145 | + datastore_content_backup = os.listdir(Path(DATASTORE_DIR) / "datastore") |
| 146 | + assert len(datastore_content_backup) == len(datastore_content) + 1 |
| 147 | + tmp_dir = Path(DATASTORE_DIR) / "datastore" / "tmp" |
| 148 | + assert os.path.isdir(tmp_dir) |
| 149 | + tmp_actual_content = os.listdir(tmp_dir) |
| 150 | + tmp_expected_content = [ |
| 151 | + "metadata_all__DRAFT.json", |
| 152 | + "datastore_versions.json", |
| 153 | + "draft_version.json", |
| 154 | + ] |
| 155 | + assert len(tmp_actual_content) == 3 |
| 156 | + for content in tmp_expected_content: |
| 157 | + assert content in tmp_actual_content |
| 158 | + |
| 159 | + |
| 160 | +def test_make_temp_directory_already_exists(): |
| 161 | + local_storage.datastore_dir.save_temporary_backup() |
| 162 | + datastore_content = os.listdir(Path(DATASTORE_DIR) / "datastore") |
| 163 | + assert "tmp" in datastore_content |
| 164 | + with pytest.raises(LocalStorageError) as e: |
| 165 | + local_storage.datastore_dir.save_temporary_backup() |
| 166 | + assert "tmp directory already exists" in str(e) |
| 167 | + |
| 168 | + |
| 169 | +def test_archive_temp_directory(): |
| 170 | + local_storage.datastore_dir.save_temporary_backup() |
| 171 | + datastore_content = os.listdir(Path(DATASTORE_DIR) / "datastore") |
| 172 | + local_storage.datastore_dir.archive_temporary_backup() |
| 173 | + datastore_content_archived = os.listdir(Path(DATASTORE_DIR) / "datastore") |
| 174 | + assert len(datastore_content) == len(datastore_content_archived) + 1 |
| 175 | + assert not os.path.isdir(Path(DATASTORE_DIR) / "datastore" / "tmp") |
| 176 | + |
| 177 | + |
| 178 | +def test_archived_temp_directory_unrecognized_files(): |
| 179 | + local_storage.datastore_dir.save_temporary_backup() |
| 180 | + tmp_dir = Path(DATASTORE_DIR) / "datastore" / "tmp" |
| 181 | + assert os.path.isdir(tmp_dir) |
| 182 | + (tmp_dir / "newfile.txt").touch() |
| 183 | + |
| 184 | + with pytest.raises(LocalStorageError) as e: |
| 185 | + local_storage.datastore_dir.archive_temporary_backup() |
| 186 | + assert "Found unrecognized files" in str(e) |
| 187 | + |
| 188 | + |
| 189 | +def test_archive_or_delete_non_existent_tmp_dir(): |
| 190 | + with pytest.raises(LocalStorageError) as e: |
| 191 | + local_storage.datastore_dir.archive_temporary_backup() |
| 192 | + assert "Could not find a tmp directory to archive." in str(e) |
| 193 | + with pytest.raises(LocalStorageError) as e: |
| 194 | + local_storage.datastore_dir.delete_temporary_backup() |
| 195 | + assert "Could not find a tmp directory to delete." in str(e) |
0 commit comments