diff --git a/README.md b/README.md index 8259c4079a5ec45d6598b0418dd4de5b0f9d7851..d8789e11305ad30ee839ddde9ae4ef617882b4fb 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,11 @@ file_list_example: an example file list file needed by clavrxorb +## Testing + +Requres py.test + +`test.sh` simply runs `py.test` in the `test/` directory. + +Sample output from select tests are saved for each release at `/ships19/cloud/archive/clavrx_test_data/version_granules` + diff --git a/test/save_record.py b/test/save_record.py new file mode 100644 index 0000000000000000000000000000000000000000..b04c987720ac544d5dcd98210bba19e118431bd6 --- /dev/null +++ b/test/save_record.py @@ -0,0 +1,24 @@ +from pathlib import Path +import test + +RECORD_DIR = Path('/ships19/cloud/archive/clavrx_test_data/version_granules') + +def main(version): + version_dir = RECORD_DIR / version + for func in test.save_funcs: + name = func.__name__ + output_dir = version_dir / name + if output_dir.exists() and len(list(output_dir.glob('*')))>0: + print(output_dir, 'already exists') + else: + output_dir.mkdir(exist_ok=True,parents=True) + print(output_dir) + func(out_dir=output_dir) + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('version') + args = parser.parse_args() + main(args.version) + diff --git a/test/test.py b/test/test.py index ddc1a3dc804ae9c68127d33969405667f07a8b56..4633df7127da449b8079892a6c5f8994dfc6630c 100644 --- a/test/test.py +++ b/test/test.py @@ -1,3 +1,16 @@ +""" +test.py + +Test cases can be added by creating a function with "test" in the name + +A helper function "_run_it()" makes it easy to add a test. + +@save decorator marks tests that we'll permanently save the output from (see save_record.py) + +@extra decorator marks tests that won't be run unless we set TEST_EXTRA=True below) + +""" + from clavrx import run_clavrx, get_config, build_options_file, build_file_list from pathlib import Path from tempfile import mkdtemp @@ -6,25 +19,54 @@ import subprocess import pytest import signal import os +import re CLAVRX = Path('../clavrx_bin/clavrxorb').absolute() assert CLAVRX.exists(), str(CLAVRX)+' does not exist' HERE = Path(__file__).absolute().parent +def get_all_l2_variables(): + l2_variables = set() + pattern = re.compile('.*case\([\'"](\w+)[\'"]\).*') + with open(HERE / '../main_src/level2_mod.f90') as fp: + for line in fp: + if 'case("' in line: + match = pattern.match(line) + if match is not None: + l2_variables.add(match.group(1)) + return sorted(l2_variables) + -L2_LIST_CONTENT = "testing\nlatitude\nlongitude\ncloud_probability\n" +L2_LIST_CONTENT = '\n'.join(['testing',*get_all_l2_variables()]) TEST_EXTRA = False extra = pytest.mark.skipif(not TEST_EXTRA, reason="extra test") -def _run_it(main_l1b_file, aux_l1b_files=(), config_override=None): +save_funcs = [] +def save(func): + save_funcs.append(func) + return func + + +def _run_it(main_l1b_file, aux_l1b_files=(), config_override=None, out_dir=None): + """ + Run clavrx case + + main_l1b_file :: the primary l1b granule + aux_l1b_files :: list of files that will get linked next to the primary file in a temp dir + config_override :: dict of clavrx options to override the defaults (see options/default_options.yml) + out_dir :: directory to persist output the l2 file (default is a temporary directory which is removed) + """ main_l1b_file = Path(main_l1b_file) tmpdir = Path(mkdtemp(dir=HERE)) try: - out_dir = tmpdir / 'out' - out_dir.mkdir() + if out_dir is None: + out_dir = tmpdir / 'out' + else: + out_dir = Path(out_dir) + out_dir.mkdir(exist_ok=True, parents=True) l1b_links = [] for f in aux_l1b_files: f = Path(f) @@ -53,7 +95,7 @@ def _run_it(main_l1b_file, aux_l1b_files=(), config_override=None): config[k][k2] = v2 else: config[k] = v - config['temp_dir'] = str(out_dir / 'temp_dir') + config['temp_dir'] = str(tmpdir) #str(out_dir / 'temp_dir') options_file_content = build_options_file(config) file_list_content = build_file_list(out_dir, [main_l1b_link]) level2_list_content = L2_LIST_CONTENT @@ -97,16 +139,30 @@ def test_pgroup_bug(): rmtree(tmpdir) -def test_viirs(): - ROOT = Path('/apollo/cloud/archive/Satellite_Input/VIIRS-N20/global/2018/098/') - VIIRS_L1_FNAME = 'GMTCO_j01_d20180407_t2358242_e2359487_b01995_c20190226192728879159_noac_ops.h5' - VIIRS_L1 = ROOT / VIIRS_L1_FNAME - _run_it(VIIRS_L1) +@save +def test_noaa_viirs(out_dir=None): + #ROOT = Path('/apollo/cloud/archive/Satellite_Input/VIIRS-N20/global/2018/098/') + #VIIRS_L1_FNAME = 'GMTCO_j01_d20180407_t2358242_e2359487_b01995_c20190226192728879159_noac_ops.h5' + ROOT = Path('/ships19/cloud/archive/clavrx_test_data/viirs/noaa') + VIIRS_L1 = ROOT / 'GMTCO_npp_d20220221_t2356569_e0002373_b53481_c20220222005748538034_oebc_ops.h5' + aux = set(ROOT.glob('*npp_d20220221_t2356569_e0002373*')) + aux.remove(VIIRS_L1) + _run_it(VIIRS_L1, aux, out_dir=out_dir) + +@save +def test_nasa_viirs(out_dir=None): + ROOT = Path('/ships19/cloud/archive/clavrx_test_data/viirs/nasa') + vnp03 = ROOT / 'VNP03MOD.A2019003.1700.002.2021102031552.nc' + extra = set(ROOT.glob('*A2019003.1700*')) + extra.remove(vnp03) + _run_it(vnp03, extra, out_dir=out_dir) + -def test_avhrr(): +@save +def test_avhrr(out_dir=None): AVHRR = Path('/arcdata/polar/noaa/noaa18/2020/2020_01_01_001/avhrr/NSS.GHRR.NN.D20001.S0000.E0143.B7532324.WI') - _run_it(AVHRR) + _run_it(AVHRR, out_dir=out_dir) def test_avhrr_get_goes_header_bug(): # This file is empty @@ -118,14 +174,16 @@ def test_avhrr_get_goes_header_bug(): assert e.returncode == 4 -def test_fusion(): +@save +def test_fusion(out_dir=None): FUSION = Path('/ships19/cloud/archive/Satellite_Input/HIRS-FUSION/NN/2020/001/NSS.GHRR.NN.D20001.S0000.E0143.B7532324.WI.fusion.nc') AVHRR = Path('/arcdata/polar/noaa/noaa18/2020/2020_01_01_001/avhrr/NSS.GHRR.NN.D20001.S0000.E0143.B7532324.WI') override = {'lut':'ecm2_lut_avhrr123_hirs_common_chs.nc'} - _run_it(FUSION, [AVHRR], config_override=override) + _run_it(FUSION, [AVHRR], config_override=override, out_dir=out_dir) -def test_g16_fd(): +@save +def test_g16_fd(out_dir=None): ROOT = Path('/arcdata/goes/grb/goes16/2020/2020_05_02_123/abi/L1b/RadF/') files = [next(ROOT.glob(f'OR_ABI-L1b-RadF-M6C{i:02d}_G16_s202012322201*.nc')) for i in range(1,17)] override = {'bounds':{ @@ -141,15 +199,16 @@ def test_g16_fd(): 'name': 'SUB' }} - _run_it(files[0], files[1:], config_override=override) + _run_it(files[0], files[1:], config_override=override, out_dir=out_dir) -def test_g16_conus(): +@save +def test_g16_conus(out_dir=None): ROOT = Path('/arcdata/goes/grb/goes16/2020/2020_05_02_123/abi/L1b/RadC/') files = [next(ROOT.glob(f'OR_ABI-L1b-RadC-M6C{i:02d}_G16_s2020123000111*.nc')) for i in range(1,17)] override = {'bounds':{ 'enable':True, - 'lat_north': 20.0, - 'lat_south': 10.0, + 'lat_north': 50.0, + 'lat_south': 40.0, 'lon_west': -90., 'lon_east': -80., 'zen_min': 0.0, @@ -159,7 +218,7 @@ def test_g16_conus(): 'name': 'SUB' }} - _run_it(files[0], files[1:], config_override=override) + _run_it(files[0], files[1:], config_override=override, out_dir=out_dir) @extra @@ -170,7 +229,8 @@ def test_process_cloud_off(): _run_it(AVHRR, config_override=override) -def test_g17_fd(): +@save +def test_g17_fd(out_dir=None): ROOT = Path('/arcdata/goes/grb/goes17/2020/2020_05_02_123/abi/L1b/RadF/') files = [next(ROOT.glob(f'OR_ABI-L1b-RadF-M6C{i:02d}_G17_s2020123222031*.nc')) for i in range(1,17)] override = {'bounds':{ @@ -186,16 +246,17 @@ def test_g17_fd(): 'name': 'SUB' }} - _run_it(files[0], files[1:], config_override=override) + _run_it(files[0], files[1:], config_override=override, out_dir=out_dir) -def test_g17_conus(): +@save +def test_g17_conus(out_dir=None): ROOT = Path('/arcdata/goes/grb/goes17/2020/2020_05_02_123/abi/L1b/RadC/') files = [next(ROOT.glob(f'OR_ABI-L1b-RadC-M6C{i:02d}_G17_s2020123222117*.nc')) for i in range(1,17)] override = {'bounds':{ 'enable':True, - 'lat_north': 20.0, - 'lat_south': 10.0, + 'lat_north': 40.0, + 'lat_south': 30.0, 'lon_west': -130., 'lon_east': -120., 'zen_min': 0.0, @@ -205,10 +266,11 @@ def test_g17_conus(): 'name': 'SUB' }} - _run_it(files[0], files[1:], config_override=override) + _run_it(files[0], files[1:], config_override=override, out_dir=out_dir) -def test_h8_fd_dat(): +@save +def test_h8_fd_dat(out_dir=None): ROOT = Path('/arcdata/nongoes/japan/himawari08/2021_01/2021_01_01_001/2300/') files = sorted(ROOT.glob('HS_H08_20210101_2300_B*_FLDK*')) override = {'bounds':{ @@ -224,6 +286,6 @@ def test_h8_fd_dat(): 'name': 'SUB' }} - _run_it(files[0], files[1:], config_override=override) + _run_it(files[0], files[1:], config_override=override, out_dir=out_dir)