Skip to content

Commit c90114f

Browse files
committed
rimport: Factor out function get_files_to_process.
1 parent fbad8c7 commit c90114f

2 files changed

Lines changed: 233 additions & 12 deletions

File tree

rimport

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,35 @@ def print_can_file_be_downloaded(file_can_be_downloaded: bool):
306306
logger.info("%sFile is not (yet) available for download.", INDENT)
307307

308308

309+
def get_files_to_process(file: str, filelist: str):
310+
"""Get list of files to process.
311+
312+
Uses either --file or --filelist. "Prefers" --file, but they're actually mutually exclusive, so
313+
don't rely on that.
314+
315+
Args:
316+
file (str): Single file to process.
317+
filelist (str): File containing list of files to process
318+
319+
Returns:
320+
list: List of files to process
321+
int: Result code
322+
"""
323+
if file is not None:
324+
files_to_process = [file]
325+
else:
326+
list_path = Path(filelist).expanduser().resolve()
327+
if not list_path.exists():
328+
logger.error("rimport: list file not found: %s", list_path)
329+
return None, 2
330+
files_to_process = read_filelist(list_path)
331+
if not files_to_process:
332+
logger.error("rimport: no filenames found in list: %s", list_path)
333+
return None, 2
334+
335+
return files_to_process, 0
336+
337+
309338
def main(argv: List[str] | None = None) -> int:
310339
"""Main entry point for the rimport tool.
311340
@@ -346,18 +375,10 @@ def main(argv: List[str] | None = None) -> int:
346375
logger.error("rimport: inputdata directory does not exist: %s", root)
347376
return 2
348377

349-
# Determine the list of filenames to handle
350-
if args.file is not None:
351-
files_to_process = [args.file]
352-
else:
353-
list_path = Path(args.filelist).expanduser().resolve()
354-
if not list_path.exists():
355-
logger.error("rimport: list file not found: %s", list_path)
356-
return 2
357-
files_to_process = read_filelist(list_path)
358-
if not files_to_process:
359-
logger.error("rimport: no filenames found in list: %s", list_path)
360-
return 2
378+
# Determine the list of relative filenames to handle
379+
files_to_process, status = get_files_to_process(args.file, args.filelist)
380+
if status:
381+
return status
361382

362383
# Resolve to full paths (keep accepting absolute names too)
363384
paths = normalize_paths(root, files_to_process)
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
"""
2+
Tests for main() function in rimport script.
3+
4+
These tests focus on the logic and control flow in main(), mocking out
5+
the helper functions to isolate main()'s behavior.
6+
"""
7+
8+
import os
9+
import importlib.util
10+
from importlib.machinery import SourceFileLoader
11+
from pathlib import Path
12+
from unittest.mock import patch, call
13+
import pytest
14+
15+
# pylint: disable=too-many-arguments,too-many-positional-arguments
16+
17+
# Import rimport module from file without .py extension
18+
rimport_path = os.path.join(
19+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
20+
"rimport",
21+
)
22+
loader = SourceFileLoader("rimport", rimport_path)
23+
spec = importlib.util.spec_from_loader("rimport", loader)
24+
if spec is None:
25+
raise ImportError(f"Could not create spec for rimport from {rimport_path}")
26+
rimport = importlib.util.module_from_spec(spec)
27+
# Don't add to sys.modules to avoid conflict with other test files (patches here not being applied)
28+
loader.exec_module(rimport)
29+
30+
31+
class TestGetRelnamesToProcess:
32+
"""Test suite for get_relnames_to_process() function."""
33+
34+
def test_single_file_relpath(self, tmp_path):
35+
"""Test giving it a single file by its relative path"""
36+
# Setup
37+
inputdata_root = tmp_path / "inputdata"
38+
inputdata_root.mkdir()
39+
staging_root = tmp_path / "staging"
40+
staging_root.mkdir()
41+
42+
filename = "test.nc"
43+
test_file = inputdata_root / filename
44+
test_file.write_text("abc123")
45+
46+
# Run
47+
files_to_process, result = rimport.get_files_to_process(
48+
file=filename, filelist=None
49+
)
50+
51+
# Verify
52+
assert result == 0
53+
assert files_to_process == [filename]
54+
55+
def test_single_file_abspath(self, tmp_path):
56+
"""Test giving it a single file by its absolute path"""
57+
# Setup
58+
inputdata_root = tmp_path / "inputdata"
59+
inputdata_root.mkdir()
60+
staging_root = tmp_path / "staging"
61+
staging_root.mkdir()
62+
63+
filename = "test.nc"
64+
test_file = inputdata_root / filename
65+
test_file.write_text("abc123")
66+
67+
# Run
68+
files_to_process, result = rimport.get_files_to_process(
69+
file=test_file, filelist=None
70+
)
71+
72+
# Verify
73+
assert result == 0
74+
assert files_to_process == [test_file]
75+
76+
def test_filelist_relpath_with_relpaths(self, tmp_path):
77+
"""Test giving it a file list by its relative path, containing relative paths"""
78+
# Setup
79+
inputdata_root = tmp_path / "inputdata"
80+
inputdata_root.mkdir()
81+
staging_root = tmp_path / "staging"
82+
staging_root.mkdir()
83+
84+
filenames = []
85+
for i in range(2):
86+
filename = f"test{i}.txt"
87+
filenames.append(filename)
88+
(inputdata_root / filename).write_text("def567")
89+
90+
filelist = tmp_path / "file_list.txt"
91+
filelist.write_text("\n".join(filenames), encoding="utf8")
92+
filelist_relpath = filelist.relative_to(os.getcwd(), walk_up=True)
93+
94+
# Run
95+
files_to_process, result = rimport.get_files_to_process(
96+
file=None, filelist=filelist_relpath
97+
)
98+
99+
# Verify
100+
assert result == 0
101+
assert files_to_process == filenames
102+
103+
def test_filelist_abspath_with_relpaths(self, tmp_path):
104+
"""Test giving it a file list by its absolute path, containing relative paths"""
105+
# Setup
106+
inputdata_root = tmp_path / "inputdata"
107+
inputdata_root.mkdir()
108+
staging_root = tmp_path / "staging"
109+
staging_root.mkdir()
110+
111+
filenames = []
112+
for i in range(2):
113+
filename = f"test{i}.txt"
114+
filenames.append(filename)
115+
(inputdata_root / filename).write_text("def567")
116+
117+
filelist = tmp_path / "file_list.txt"
118+
filelist.write_text("\n".join(filenames), encoding="utf8")
119+
120+
# Run
121+
files_to_process, result = rimport.get_files_to_process(
122+
file=None, filelist=filelist
123+
)
124+
125+
# Verify
126+
assert result == 0
127+
assert files_to_process == filenames
128+
129+
def test_filelist_relpath_with_abspaths(self, tmp_path):
130+
"""Test giving it a file list by its relative path, containing absolute paths"""
131+
# Setup
132+
inputdata_root = tmp_path / "inputdata"
133+
inputdata_root.mkdir()
134+
staging_root = tmp_path / "staging"
135+
staging_root.mkdir()
136+
137+
filenames = []
138+
for i in range(2):
139+
filename = inputdata_root / f"test{i}.txt"
140+
filenames.append(str(filename))
141+
filename.write_text("def567")
142+
143+
filelist = tmp_path / "file_list.txt"
144+
filelist.write_text("\n".join(filenames), encoding="utf8")
145+
filelist_relpath = filelist.relative_to(os.getcwd(), walk_up=True)
146+
147+
# Run
148+
files_to_process, result = rimport.get_files_to_process(
149+
file=None, filelist=filelist_relpath
150+
)
151+
152+
# Verify
153+
assert result == 0
154+
assert files_to_process == filenames
155+
156+
def test_filelist_abspath_with_abspaths(self, tmp_path):
157+
"""Test giving it a file list by its absolute path, containing absolute paths"""
158+
# Setup
159+
inputdata_root = tmp_path / "inputdata"
160+
inputdata_root.mkdir()
161+
staging_root = tmp_path / "staging"
162+
staging_root.mkdir()
163+
164+
filenames = []
165+
for i in range(2):
166+
filename = inputdata_root / f"test{i}.txt"
167+
filenames.append(str(filename))
168+
filename.write_text("def567")
169+
170+
filelist = tmp_path / "file_list.txt"
171+
filelist.write_text("\n".join(filenames), encoding="utf8")
172+
173+
# Run
174+
files_to_process, result = rimport.get_files_to_process(
175+
file=None, filelist=filelist
176+
)
177+
178+
# Verify
179+
assert result == 0
180+
assert files_to_process == filenames
181+
182+
def test_filelist_not_found(self):
183+
"""Test giving it a file list that doesn't exist"""
184+
filelist = "bsfearirn"
185+
assert not os.path.exists(filelist)
186+
files_to_process, result = rimport.get_files_to_process(
187+
file=None, filelist=filelist
188+
)
189+
assert result == 2
190+
assert files_to_process is None
191+
192+
def test_filelist_empty(self, tmp_path):
193+
"""Test giving it an empty file list"""
194+
filelist = tmp_path / "bsfearirn"
195+
filelist.write_text("")
196+
files_to_process, result = rimport.get_files_to_process(
197+
file=None, filelist=filelist
198+
)
199+
assert result == 2
200+
assert files_to_process is None

0 commit comments

Comments
 (0)