Skip to content
Snippets Groups Projects
Commit 02e9c4de authored by Alan De Smet's avatar Alan De Smet
Browse files

Improve tests

Correctly handle desired empty stdout/stder, print all errors of
stdout/stderr/returnode, not just the first we notice
parent 06360732
No related branches found
No related tags found
No related merge requests found
...@@ -10,11 +10,30 @@ import re ...@@ -10,11 +10,30 @@ import re
import datetime import datetime
from textwrap import dedent from textwrap import dedent
def assert_pattern_matches_string(description, pattern, string): def assert_stdout_err_ret(expected_stdout, stdout, expected_stderr, stderr, expected_returncode, returncode):
if pattern is None: return """ Verify stdout, stderr, and return code from a program.
We test all three at once, as all three are often useful in diagnosing
the problem if any of them is wrong.
"""
if (re.search(expected_stdout, stdout) and
re.search(expected_stderr, stderr) and
expected_returncode == returncode
):
return
msg = "Program did not return expected results.\n"
if expected_stdout is not None and not re.search(expected_stdout, stdout):
msg += f"Standard output does not match expectation.\nExpected regular repression:\n {repr(expected_stdout)}\nActual:\n {repr(stdout)}\n"
if expected_stderr is not None and not re.search(expected_stderr, stderr):
msg += f"Standard error does not match expectation.\nExpected regular repression:\n {repr(expected_stderr)}\nActual:\n {repr(stderr)}\n"
if expected_returncode != returncode:
msg += f"Return code should have been {expected_returncode} but is {returncode}.\n"
raise AssertionError(msg)
if not re.search(pattern, string):
raise AssertionError(f"{description} does not match expectation.\nExpected regular repression:\n{repr(pattern)}\nActual:\n{repr(string)}")
class TestCase (csppfetch.test_extensions.TestCase): class TestCase (csppfetch.test_extensions.TestCase):
def assertDownloadCommand(self, cmd, web_files, expected_files, expected_stdout=None, expected_stderr=None, expected_returncode=0): def assertDownloadCommand(self, cmd, web_files, expected_files, expected_stdout=None, expected_stderr=None, expected_returncode=0):
...@@ -29,8 +48,9 @@ class TestCase (csppfetch.test_extensions.TestCase): ...@@ -29,8 +48,9 @@ class TestCase (csppfetch.test_extensions.TestCase):
CSPP_GEO_AITF_ANCIL_CONNECT_TIMEOUT="0.1", CSPP_GEO_AITF_ANCIL_CONNECT_TIMEOUT="0.1",
CSPP_GEO_AITF_ANCIL_RETRY_WAIT="0"): CSPP_GEO_AITF_ANCIL_RETRY_WAIT="0"):
ret = subprocess.run(cmd, capture_output=True, text=True) ret = subprocess.run(cmd, capture_output=True, text=True)
assert_pattern_matches_string("Standard error", expected_stderr, ret.stderr) assert_stdout_err_ret(expected_stdout, ret.stdout,
assert_pattern_matches_string("Standard output", expected_stdout, ret.stdout) expected_stderr, ret.stderr,
expected_returncode, ret.returncode)
self.assertEqual(ret.returncode,expected_returncode) self.assertEqual(ret.returncode,expected_returncode)
self.assertDirectoryContents(outdir, expected_files) self.assertDirectoryContents(outdir, expected_files)
...@@ -81,8 +101,8 @@ class Test_aitf_data_for_run (TestCase): ...@@ -81,8 +101,8 @@ class Test_aitf_data_for_run (TestCase):
"gfs_grib2_0.5deg/2023/02/09/gfs.t00z.pgrbf06": 'gfs.t00z.230209.pgrb2f06', "gfs_grib2_0.5deg/2023/02/09/gfs.t00z.pgrbf06": 'gfs.t00z.230209.pgrb2f06',
"oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None "oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None
}, },
expected_stdout = "", expected_stdout = "^$",
expected_stderr = "" expected_stderr = "^$"
) )
def test_simple_case(self): def test_simple_case(self):
...@@ -107,7 +127,7 @@ class Test_aitf_data_for_run (TestCase): ...@@ -107,7 +127,7 @@ class Test_aitf_data_for_run (TestCase):
"oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None "oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None
}, },
expected_stdout = data_for_run_output(SST_files=1, GFS_files=2), expected_stdout = data_for_run_output(SST_files=1, GFS_files=2),
expected_stderr = "" expected_stderr = "^$"
) )
def test_older_OISST(self): def test_older_OISST(self):
...@@ -132,7 +152,7 @@ class Test_aitf_data_for_run (TestCase): ...@@ -132,7 +152,7 @@ class Test_aitf_data_for_run (TestCase):
"oisst_daily/avhrr-only-v2.20230208_preliminary.nc": None "oisst_daily/avhrr-only-v2.20230208_preliminary.nc": None
}, },
expected_stdout = data_for_run_output(SST_files=1, GFS_files=2), expected_stdout = data_for_run_output(SST_files=1, GFS_files=2),
expected_stderr = "" expected_stderr = "^$"
) )
def test_older_GFS(self): def test_older_GFS(self):
...@@ -156,7 +176,7 @@ class Test_aitf_data_for_run (TestCase): ...@@ -156,7 +176,7 @@ class Test_aitf_data_for_run (TestCase):
"oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None "oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None
}, },
expected_stdout = data_for_run_output(SST_files=1, GFS_files=2), expected_stdout = data_for_run_output(SST_files=1, GFS_files=2),
expected_stderr = "" expected_stderr = "^$"
) )
def test_missing_GFS(self): def test_missing_GFS(self):
...@@ -185,7 +205,7 @@ class Test_aitf_data_for_run (TestCase): ...@@ -185,7 +205,7 @@ class Test_aitf_data_for_run (TestCase):
"oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None "oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None
}, },
expected_stdout = expected_stdout, expected_stdout = expected_stdout,
expected_stderr = "", expected_stderr = "^$",
expected_returncode = 1, expected_returncode = 1,
) )
...@@ -223,7 +243,7 @@ class Test_aitf_data_for_run (TestCase): ...@@ -223,7 +243,7 @@ class Test_aitf_data_for_run (TestCase):
#"gfs_grib2_0.5deg/2023/02/09/gfs.t00z.pgrbf06": 'gfs.t00z.230209.pgrb2f06', #"gfs_grib2_0.5deg/2023/02/09/gfs.t00z.pgrbf06": 'gfs.t00z.230209.pgrb2f06',
}, },
expected_stdout = expected_stdout, expected_stdout = expected_stdout,
expected_stderr = "", expected_stderr = "^$",
expected_returncode = 1, expected_returncode = 1,
) )
...@@ -239,9 +259,9 @@ class Test_aitf_data_for_run (TestCase): ...@@ -239,9 +259,9 @@ class Test_aitf_data_for_run (TestCase):
"oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None, "oisst_daily/avhrr-only-v2.20230209_preliminary.nc": None,
} }
expected_stdout_1 = data_for_run_output(SST_files=1, GFS_files=2) expected_stdout_1 = data_for_run_output(SST_files=1, GFS_files=2)
expected_stderr_1 = "" expected_stderr_1 = "^$"
expected_stdout_2 = data_for_run_output(SST_files=0, GFS_files=0, SST_cache_files=1, GFS_cache_files=2) expected_stdout_2 = data_for_run_output(SST_files=0, GFS_files=0, SST_cache_files=1, GFS_cache_files=2)
expected_stderr_2 = "" expected_stderr_2 = "^$"
with tempfile.TemporaryDirectory(prefix="csppfetch-test") as outdir: with tempfile.TemporaryDirectory(prefix="csppfetch-test") as outdir:
with PopulatedManagedWebserver(web_files) as url: with PopulatedManagedWebserver(web_files) as url:
...@@ -250,15 +270,15 @@ class Test_aitf_data_for_run (TestCase): ...@@ -250,15 +270,15 @@ class Test_aitf_data_for_run (TestCase):
CSPP_GEO_AITF_ANCIL_RETRY_WAIT="1"): CSPP_GEO_AITF_ANCIL_RETRY_WAIT="1"):
cmd = ["./aitf-data-for-run", "-v", "--cache", outdir, "2023-02-09T03:00:00"] cmd = ["./aitf-data-for-run", "-v", "--cache", outdir, "2023-02-09T03:00:00"]
ret = subprocess.run(cmd , capture_output=True, text=True) ret = subprocess.run(cmd , capture_output=True, text=True)
assert_pattern_matches_string("Standard error", expected_stderr_1, ret.stderr) assert_stdout_err_ret(expected_stdout_1, ret.stdout,
assert_pattern_matches_string("Standard output", expected_stdout_1, ret.stdout) expected_stderr_1, ret.stderr,
self.assertEqual(ret.returncode,0) 0, ret.returncode)
self.assertDirectoryContents(outdir, expected_files) self.assertDirectoryContents(outdir, expected_files)
ret = subprocess.run(cmd , capture_output=True, text=True) ret = subprocess.run(cmd , capture_output=True, text=True)
assert_pattern_matches_string("Standard error", expected_stderr_2, ret.stderr) assert_stdout_err_ret(expected_stdout_2, ret.stdout,
assert_pattern_matches_string("Standard output", expected_stdout_2, ret.stdout) expected_stderr_2, ret.stderr,
self.assertEqual(ret.returncode,0) 0, ret.returncode)
self.assertDirectoryContents(outdir, expected_files) self.assertDirectoryContents(outdir, expected_files)
class Test_aitf_update_cache (TestCase): class Test_aitf_update_cache (TestCase):
...@@ -320,8 +340,8 @@ class Test_aitf_update_cache (TestCase): ...@@ -320,8 +340,8 @@ class Test_aitf_update_cache (TestCase):
["./aitf-update-cache", "--newest", "2023-02-15", "CACHEDIR"], ["./aitf-update-cache", "--newest", "2023-02-15", "CACHEDIR"],
web_files=web_files, web_files=web_files,
expected_files=expected_files, expected_files=expected_files,
expected_stdout="", expected_stdout="^$",
expected_stderr="", expected_stderr="^$",
) )
@unittest.skip("not yet implemented") @unittest.skip("not yet implemented")
...@@ -355,8 +375,8 @@ class Test_aitf_update_cache (TestCase): ...@@ -355,8 +375,8 @@ class Test_aitf_update_cache (TestCase):
["./aitf-update-cache", "--newest", "2023-02-09T13:20:00", "--oldest", "2023-02-09T13:10:00", "CACHEDIR"], ["./aitf-update-cache", "--newest", "2023-02-09T13:20:00", "--oldest", "2023-02-09T13:10:00", "CACHEDIR"],
web_files=web_files, web_files=web_files,
expected_files=expected_files, expected_files=expected_files,
expected_stdout="", expected_stdout="^$",
expected_stderr="", expected_stderr="^$",
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment