Skip to content

Commit a68cf59

Browse files
authored
Merge pull request #117 from falconstryker/devel
Fixed MarsPull Tests
2 parents c955217 + f770d8a commit a68cf59

File tree

2 files changed

+124
-91
lines changed

2 files changed

+124
-91
lines changed

bin/MarsPull.py

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,10 @@ def debug_wrapper(func):
5353
:raises Exception: If an error occurs during the function call.
5454
:raises TypeError: If the function is not callable.
5555
:raises ValueError: If the function is not found.
56-
:raises NameError: If the function is not defined.
5756
:raises AttributeError: If the function does not have the
5857
specified attribute.
59-
:raises ImportError: If the function cannot be imported.
60-
:raises RuntimeError: If the function cannot be run.
61-
:raises KeyError: If the function does not have the
62-
specified key.
6358
:raises IndexError: If the function does not have the
6459
specified index.
65-
:raises IOError: If the function cannot be opened.
66-
:raises OSError: If the function cannot be accessed.
67-
:raises EOFError: If the function cannot be read.
68-
:raises MemoryError: If the function cannot be allocated.
69-
:raises OverflowError: If the function cannot be overflowed.
70-
:raises ZeroDivisionError: If the function cannot be divided by zero.
71-
:raises StopIteration: If the function cannot be stopped.
72-
:raises KeyboardInterrupt: If the function cannot be interrupted.
73-
:raises SystemExit: If the function cannot be exited.
74-
:raises AssertionError: If the function cannot be asserted.
7560
"""
7661

7762
@functools.wraps(func)
@@ -319,7 +304,7 @@ def main():
319304
global debug
320305

321306
if not args.list_files and not args.directory_name:
322-
print('Error: You must specify either -list or a directory.')
307+
print(f'{Red}ERROR: You must specify either -list or a directory.{Nclr}')
323308
sys.exit(1)
324309

325310
base_dir = 'https://data.nas.nasa.gov'
@@ -362,30 +347,39 @@ def main():
362347
# )
363348
fv3_urls = [f'{fv3_data_url}']
364349

365-
print(f'\nSearching for available directories...')
366-
print(f'--------------------------------------')
367-
for url in legacy_urls:
368-
legacy_dir_option = url.split('legacygcmdata/')[1]
369-
print(f'{"(Legacy MGCM)":<17} {legacy_dir_option:<20} '
370-
f'{Cyan}{url}{Nclr}')
371-
372-
# NOTE: See above comment for the FV3-based MGCM data note
373-
# for url in fv3_urls:
374-
# fv3_dir_option = url.split('fv3betaout1data/')[1]
375-
# print(f'{"(FV3-based MGCM)":<17} {fv3_dir_option:<17} '
376-
# f'{Cyan}{url}{Nclr}')
377-
print(f'{"(FV3-based MGCM)":<17} {"FV3BETAOUT1":<20} '
378-
f'{Cyan}{fv3_home_url}{Nclr}')
379-
print(f'---------------------\n')
380-
350+
print(f'\nSearching for available directories...\n')
351+
if legacy_urls != []:
352+
for url in legacy_urls:
353+
legacy_dir_option = url.split('legacygcmdata/')[1]
354+
print(f'{"(Legacy MGCM)":<17} {legacy_dir_option:<20} '
355+
f'{Cyan}{url}{Nclr}')
356+
357+
# NOTE: See above comment for the FV3-based MGCM data note
358+
# for url in fv3_urls:
359+
# fv3_dir_option = url.split('fv3betaout1data/')[1]
360+
# print(f'{"(FV3-based MGCM)":<17} {fv3_dir_option:<17} '
361+
# f'{Cyan}{url}{Nclr}')
362+
print(f'{"(FV3-based MGCM)":<17} {"FV3BETAOUT1":<20} '
363+
f'{Cyan}{fv3_home_url}{Nclr}')
364+
365+
print(f'{Yellow}\nYou can list the files in a directory by using '
366+
f'the -list option with a directory name, e.g.\n'
367+
f'> MarsPull -list ACTIVECLDS{Nclr}\n')
368+
369+
else:
370+
print(f'{Red}No directories were found. This may be because the '
371+
f'file system is unavailable or unresponsive.\nCheck the '
372+
f'URL below to confirm. Otherwise, run with --debug for '
373+
f'more info.\n\n{Nclr}Check URL: '
374+
f'{Cyan}https://data.nas.nasa.gov/mcmcref{Nclr}\n')
375+
381376
if args.directory_name:
382377
# If a directory is provided, list the files in that directory
383378
portal_dir = args.directory_name
384379
if portal_dir == 'FV3BETAOUT1':
385380
# FV3-based MGCM
386381
print(f'\n{Green}Selected: (FV3-based MGCM) FV3BETAOUT1{Nclr}')
387-
print(f'\nSearching for available files...')
388-
print(f'--------------------------------')
382+
print(f'\nSearching for available files...\n')
389383
fv3_dir_url = f'{fv3_home_url}'
390384
fv3_data = requests.get(fv3_dir_url)
391385
fv3_file_text = fv3_data.text
@@ -434,7 +428,10 @@ def main():
434428
if fv3_files_available:
435429
print_file_list(fv3_files_available)
436430
else:
437-
print('No .nc files found. Run with --debug for more info')
431+
print(f'{Red}No .nc files found. This may be because the '
432+
f'file system is unavailable or unresponsive.\n'
433+
f'Check the URL below to confirm. Otherwise, run '
434+
f'with --debug for more info.{Nclr}')
438435
if debug:
439436
# Try a different approach for debugging
440437
table_rows = re.findall(
@@ -446,24 +443,23 @@ def main():
446443
if '.nc' in row:
447444
print(f'Debug - Found row with .nc: {row}')
448445

449-
print(f'---------------')
450446
# The download URL differs from the listing URL
451447
print(f'{Cyan}({fv3_dir_url}){Nclr}\n')
452448

453-
print(f'{Yellow}You can download files using the -f '
454-
f'option with the directory name, e.g.\n'
455-
f'> MarsPull FV3BETAOUT1 -f 03340.fixed.nc\n'
456-
f'> MarsPull FV3BETAOUT1 -f 03340.fixed.nc '
457-
f'03340.atmos_average.nc{Nclr}\n')
449+
if fv3_files_available:
450+
print(f'{Yellow}\nYou can download files using the -f '
451+
f'option with the directory name, e.g.\n'
452+
f'> MarsPull FV3BETAOUT1 -f 03340.fixed.nc\n'
453+
f'> MarsPull FV3BETAOUT1 -f 03340.fixed.nc '
454+
f'03340.atmos_average.nc{Nclr}\n')
458455

459456
elif portal_dir in [
460457
'ACTIVECLDS', 'INERTCLDS', 'NEWBASE_ACTIVECLDS',
461458
'ACTIVECLDS_NCDF'
462459
]:
463460
# Legacy MGCM
464461
print(f'\n{Green}Selected: (Legacy MGCM) {portal_dir}{Nclr}')
465-
print(f'\nAvailable files:')
466-
print(f'---------------')
462+
print(f'\nSearching for available files...\n')
467463
legacy_dir_url = (f'{legacy_data_url}' + portal_dir + r'/')
468464
legacy_data = requests.get(legacy_dir_url)
469465
legacy_file_text = legacy_data.text
@@ -495,28 +491,30 @@ def main():
495491
)
496492
legacy_files_available = href_files
497493

498-
print_file_list(legacy_files_available)
499-
print(f'---------------')
494+
# Print the files
495+
if legacy_files_available:
496+
print_file_list(legacy_files_available)
497+
else:
498+
print(f'{Red}No fort.11 files found. This may be because '
499+
f'the file system is unavailable or unresponsive.\n'
500+
f'Check the URL below to confirm. Otherwise, run '
501+
f'with --debug for more info.{Nclr}')
502+
500503
print(f'{Cyan}({legacy_dir_url}){Nclr}\n')
501504

502-
print(f'{Yellow}You can download these files using the '
503-
f'-f or -ls options with the directory name, e.g.\n'
504-
f'> MarsPull ACTIVECLDS -f fort.11_0690\n'
505-
f'> MarsPull ACTIVECLDS -f fort.11_0700 fort.11_0701 \n'
506-
f'> MarsPull ACTIVECLDS -ls 90\n'
507-
f'> MarsPull ACTIVECLDS -ls 90 180{Nclr}\n')
505+
if legacy_files_available:
506+
print(f'{Yellow}\nYou can download these files using the '
507+
f'-f or -ls options with the directory name, e.g.\n'
508+
f'> MarsPull ACTIVECLDS -f fort.11_0690\n'
509+
f'> MarsPull ACTIVECLDS -f fort.11_0700 fort.11_0701 \n'
510+
f'> MarsPull ACTIVECLDS -ls 90\n'
511+
f'> MarsPull ACTIVECLDS -ls 90 180{Nclr}\n')
508512

509513
else:
510-
print(f'Error: Directory {portal_dir} does not exist.')
514+
print(f'{Red}ERROR: Directory {portal_dir} does not exist.{Nclr}')
511515
sys.exit(1)
512516
sys.exit(0)
513517

514-
else:
515-
# If no directory is provided, exit with an error
516-
print(f'{Yellow}You can list the files in a directory by using '
517-
f'the -list option with a directory name, e.g.\n'
518-
f'> MarsPull -list ACTIVECLDS{Nclr}\n')
519-
520518
if args.directory_name and not args.list_files:
521519
portal_dir = args.directory_name
522520
if portal_dir in [
@@ -527,7 +525,7 @@ def main():
527525
requested_url = (f'{fv3_data_url}')
528526

529527
if not (args.ls or args.filename):
530-
print(f'{Yellow}ERROR No file requested. Use [-ls --ls] or '
528+
print(f'{Red}ERROR No file requested. Use [-ls --ls] or '
531529
f'[-f --filename] to specify a file to download.{Nclr}')
532530
sys.exit(1) # Return a non-zero exit code
533531
portal_dir = args.directory_name
@@ -587,7 +585,7 @@ def main():
587585

588586
elif not args.list_files:
589587
# If no directory is provided and its not a -list request
590-
print(f'{Yellow}ERROR: A directory must be specified unless using '
588+
print(f'{Red}ERROR: A directory must be specified unless using '
591589
f'-list.{Nclr}')
592590
sys.exit(1)
593591

tests/test_marspull.py

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,122 +15,157 @@
1515

1616
class TestMarsPull(unittest.TestCase):
1717
"""Integration test suite for MarsPull"""
18-
18+
1919
@classmethod
2020
def setUpClass(cls):
2121
"""Set up the test environment"""
2222
# Create a temporary directory in the user's home directory
2323
cls.test_dir = os.path.join(os.path.expanduser('~'), 'MarsPull_test_downloads')
2424
os.makedirs(cls.test_dir, exist_ok=True)
25-
25+
2626
# Project root directory
2727
cls.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
28-
28+
2929
def setUp(self):
3030
"""Change to temporary directory before each test"""
3131
os.chdir(self.test_dir)
32-
32+
3333
@classmethod
3434
def tearDownClass(cls):
3535
"""Clean up the test environment"""
3636
try:
3737
shutil.rmtree(cls.test_dir, ignore_errors=True)
3838
except Exception:
3939
print(f"Warning: Could not remove test directory {cls.test_dir}")
40-
40+
4141
def run_mars_pull(self, args):
4242
"""
4343
Run MarsPull using subprocess to avoid import-time argument parsing
44-
44+
4545
:param args: List of arguments to pass to MarsPull
4646
"""
4747
# Construct the full command to run MarsPull
4848
cmd = [sys.executable, '-m', 'bin.MarsPull'] + args
49-
49+
5050
# Run the command
5151
try:
5252
result = subprocess.run(
53-
cmd,
54-
capture_output=True,
55-
text=True,
53+
cmd,
54+
capture_output=True,
55+
text=True,
5656
cwd=self.test_dir, # Run in the test directory
5757
env=dict(os.environ, PWD=self.test_dir) # Ensure current working directory is set
5858
)
59-
59+
6060
# Check if the command was successful
6161
if result.returncode != 0:
6262
self.fail(f"MarsPull failed with error: {result.stderr}")
63-
63+
6464
return result
6565
except Exception as e:
6666
self.fail(f"Failed to run MarsPull: {e}")
67-
67+
6868
def check_files_in_test_directory(self, expected_files):
6969
"""
7070
Check if files exist in the test directory
71-
71+
7272
If files are not found, list all files in the directory to help diagnose the issue
7373
"""
7474
test_files = os.listdir(self.test_dir)
75-
75+
7676
for filename in expected_files:
7777
if filename not in test_files:
7878
print(f"Files in test directory ({self.test_dir}):")
7979
print(test_files)
8080
self.fail(f"File {filename} was not found in the test directory")
81-
81+
8282
# Verify file is not empty
8383
filepath = os.path.join(self.test_dir, filename)
84-
self.assertGreater(os.path.getsize(filepath), 0,
84+
self.assertGreater(os.path.getsize(filepath), 0,
8585
f"Downloaded file {filename} is empty")
86-
86+
8787
def test_download_fv3betaout1_specific_file(self):
8888
"""Test downloading a specific file from FV3BETAOUT1"""
8989
result = self.run_mars_pull(['FV3BETAOUT1', '-f', '03340.fixed.nc'])
90-
90+
9191
# Check that the file was created
9292
self.check_files_in_test_directory(['03340.fixed.nc'])
93-
93+
9494
def test_download_inertclds_single_ls(self):
9595
"""Test downloading files from INERTCLDS for a single Ls value"""
9696
result = self.run_mars_pull(['INERTCLDS', '-ls', '90'])
97-
97+
9898
# Check that the file was created
9999
self.check_files_in_test_directory(['fort.11_0689'])
100-
100+
101101
def test_download_inertclds_ls_range(self):
102102
"""Test downloading files from INERTCLDS for a range of Ls values"""
103103
result = self.run_mars_pull(['INERTCLDS', '-ls', '90', '95'])
104-
104+
105105
# Check that the files were created
106106
self.check_files_in_test_directory(['fort.11_0689', 'fort.11_0690'])
107-
107+
108108
def test_list_option(self):
109109
"""Test the list option to ensure it runs without errors"""
110110
result = self.run_mars_pull(['-list'])
111-
111+
112112
# Check that something was printed
113113
self.assertTrue(len(result.stdout) > 0, "No output generated by -list option")
114-
114+
115115
# Check for specific expected output
116-
self.assertIn("Available directories", result.stdout)
117-
self.assertIn("Available files", result.stdout)
116+
self.assertIn("Searching for available directories", result.stdout)
117+
118+
# Check for possible outputs - either directories found or error message
119+
if "No directories were found" in result.stdout:
120+
# Check error message when no directories found
121+
self.assertIn("No directories were found", result.stdout)
122+
self.assertIn("file system is unavailable or unresponsive", result.stdout)
123+
self.assertIn("Check URL:", result.stdout)
124+
else:
125+
# If directories are found, check the expected output format
126+
self.assertIn("(FV3-based MGCM)", result.stdout)
127+
self.assertIn("FV3BETAOUT1", result.stdout)
128+
self.assertIn("You can list the files in a directory", result.stdout)
129+
130+
def test_list_directory_option(self):
131+
"""Test the list option with a directory to ensure it runs without errors"""
132+
result = self.run_mars_pull(['-list', 'FV3BETAOUT1'])
133+
134+
# Check that something was printed
135+
self.assertTrue(len(result.stdout) > 0, "No output generated by -list FV3BETAOUT1 option")
136+
137+
# Check for expected output sections
138+
self.assertIn("Selected: (FV3-based MGCM) FV3BETAOUT1", result.stdout)
139+
self.assertIn("Searching for available files", result.stdout)
140+
141+
# Check for possible outputs - either files found or error message
142+
if "No .nc files found" in result.stdout:
143+
# Check error message when no files found
144+
self.assertIn("No .nc files found", result.stdout)
145+
self.assertIn("file system is unavailable or unresponsive", result.stdout)
146+
elif "You can download files using the -f option" in result.stdout:
147+
# If files are found, check the expected usage information
148+
self.assertIn("You can download files using the -f option", result.stdout)
149+
150+
# Note: We're not checking for actual files as they might not be available
151+
# if the server is down, which is OK according to requirements
118152

153+
119154
def test_help_message(self):
120155
"""Test that help message can be displayed"""
121156
result = self.run_mars_pull(['-h'])
122-
157+
123158
# Check that something was printed
124159
self.assertTrue(len(result.stdout) > 0, "No help message generated")
125-
160+
126161
# Check for typical help message components
127162
help_checks = [
128163
'usage:',
129164
'-ls',
130165
'-f',
131166
'--list'
132167
]
133-
168+
134169
for check in help_checks:
135170
self.assertIn(check, result.stdout.lower(), f"Help message missing '{check}'")
136171

0 commit comments

Comments
 (0)