@@ -324,7 +324,7 @@ def distribrun(self, testdir, cmd, logfile=None, dataname=None, nisarimg=False,
324
324
--rm -i { self .tty } { img } sh -ci"
325
325
run_with_logging (dockercall , cmd , logger , printlog = self .printlog )
326
326
327
- def workflowtest (self , wfname , testname , dataname , pyname , arg = "" ): # hmmmmmmmmm
327
+ def workflowtest (self , wfname , testname , dataname , pyname , suf = "" , description = "" , arg = "" ):
328
328
"""
329
329
Run the specified workflow test using the distrib image.
330
330
@@ -334,22 +334,42 @@ def workflowtest(self, wfname, testname, dataname, pyname, arg=""): # hmmmmmmmmm
334
334
Workflow name (e.g. "rslc")
335
335
testname : str
336
336
Workflow test name (e.g. "RSLC_REE1")
337
- dataname : str
338
- Test input data (e.g. "L0B_RRSD_REE1")
337
+ dataname : str or iterable of str or None
338
+ Test input dataset(s) to be mounted (e.g. "L0B_RRSD_REE1", ["L0B_RRSD_REE1", "L0B_RRSD_REE2"]).
339
+ If None, no input datasets are used.
339
340
pyname : str
340
341
Name of the isce3 module to execute (e.g. "pybind_nisar.workflows.focus")
342
+ suf: str
343
+ Suffix in runconfig and output directory name to differentiate between
344
+ reference and secondary data in end-to-end tests
345
+ description: str
346
+ Extra test description to print out to differentiate between
347
+ reference and secondary data in end-to-end tests
341
348
arg : str, optional
342
349
Additional command line argument(s) to pass to the workflow
343
350
"""
344
- print (f"\n Running workflow test { testname } \n " )
351
+ print (f"\n Running workflow test { testname } { description } \n " )
345
352
testdir = os .path .abspath (pjoin (self .testdir , testname ))
346
- os .makedirs (pjoin (testdir , f"output_{ wfname } " ), exist_ok = True )
347
- os .makedirs (pjoin (testdir , f"scratch_{ wfname } " ), exist_ok = True )
348
- # copy test runconfig to test directory
349
- shutil .copyfile (pjoin (runconfigdir , f"{ testname } .yaml" ),
350
- pjoin (testdir , f"runconfig_{ wfname } .yaml" ))
351
- log = pjoin (testdir , f"output_{ wfname } " , "stdouterr.log" )
352
- cmd = [f"time python3 -m { pyname } { arg } runconfig_{ wfname } .yaml" ]
353
+ # create input directories before docker volume mount to avoid root ownership
354
+ # of these directories
355
+ if dataname is not None :
356
+ if type (dataname ) is not list :
357
+ dataname = [dataname ]
358
+ for data in dataname :
359
+ os .makedirs (pjoin (testdir , f"input_{ data } " ), exist_ok = True )
360
+ # create output directories
361
+ os .makedirs (pjoin (testdir , f"output_{ wfname } { suf } " ), exist_ok = True )
362
+ os .makedirs (pjoin (testdir , f"scratch_{ wfname } { suf } " ), exist_ok = True )
363
+ # copy test runconfig to test directory (for end-to-end testing, we need to
364
+ # distinguish between the runconfig files for each individual workflow)
365
+ if testname .startswith ("end2end" ):
366
+ inputrunconfig = f"{ testname } _{ wfname } { suf } .yaml"
367
+ else :
368
+ inputrunconfig = f"{ testname } { suf } .yaml"
369
+ shutil .copyfile (pjoin (runconfigdir , inputrunconfig ),
370
+ pjoin (testdir , f"runconfig_{ wfname } { suf } .yaml" ))
371
+ log = pjoin (testdir , f"output_{ wfname } { suf } " , "stdouterr.log" )
372
+ cmd = [f"time python3 -m { pyname } { arg } runconfig_{ wfname } { suf } .yaml" ]
353
373
try :
354
374
self .distribrun (testdir , cmd , logfile = log , dataname = dataname ,
355
375
loghdlrname = f'wftest.{ os .path .basename (testdir )} ' )
@@ -380,6 +400,32 @@ def insartest(self, tests=None):
380
400
for testname , dataname in tests :
381
401
self .workflowtest ("insar" , testname , dataname , "pybind_nisar.workflows.insar" , arg = "--restart" )
382
402
403
+ def end2endtest (self , tests = None ):
404
+ """
405
+ Run all workflows for one pair of L0B input data, including RSLC, GSLC, GCOV, RIFG, RUNW, GUNW.
406
+ The GSLC, GCOV, and InSAR products are generated from outputs of the RSLC workflow.
407
+ """
408
+ if tests is None :
409
+ tests = workflowtests ['end2end' ].items ()
410
+ for testname , dataname in tests :
411
+ # copy runconfigs and create output direcotories
412
+ testdir = os .path .abspath (pjoin (self .testdir , testname ))
413
+ for wfname in ['rslc' , 'gslc' , 'gcov' , 'insar' ]:
414
+ if wfname == 'rslc' :
415
+ pyname = 'pybind_nisar.workflows.focus'
416
+ else :
417
+ pyname = f'pybind_nisar.workflows.{ wfname } '
418
+
419
+ if wfname == 'insar' :
420
+ self .workflowtest (wfname , testname , dataname , pyname , arg = "--restart" ,
421
+ description = " InSAR product" )
422
+ else :
423
+ self .workflowtest (wfname , testname , dataname , pyname , suf = "_ref" ,
424
+ description = f" { wfname .upper ()} reference product" )
425
+ self .workflowtest (wfname , testname , dataname , pyname , suf = "_sec" ,
426
+ description = f" { wfname .upper ()} secondary product" )
427
+
428
+
383
429
def noisesttest (self , tests = None ):
384
430
if tests is None :
385
431
tests = workflowtests ['noisest' ].items ()
@@ -443,7 +489,7 @@ def mintests(self):
443
489
self .ptatest (tests = list (workflowtests ['pta' ].items ())[:1 ])
444
490
self .beamformtest (tests = list (workflowtests ['beamform' ].items ())[:1 ])
445
491
446
- def workflowqa (self , wfname , testname ):
492
+ def workflowqa (self , wfname , testname , suf = "" , description = "" ):
447
493
"""
448
494
Run QA and CF compliance checking for the specified workflow using the NISAR distrib image.
449
495
@@ -453,15 +499,22 @@ def workflowqa(self, wfname, testname):
453
499
Workflow name (e.g. "rslc")
454
500
testname: str
455
501
Workflow test name (e.g. "RSLC_REE1")
456
- """
457
- print (f"\n Running workflow QA on test { testname } \n " )
502
+ suf: str
503
+ Suffix in runconfig and output directory name to differentiate between
504
+ reference and secondary data in end-to-end tests
505
+ description: str
506
+ Extra test description to print out to differentiate between
507
+ reference and secondary data in end-to-end tests
508
+ """
509
+ print (f"\n Running workflow QA on test { testname } { description } \n " )
458
510
testdir = os .path .abspath (pjoin (self .testdir , testname ))
459
- os .makedirs (pjoin (testdir , f"qa_{ wfname } " ), exist_ok = True )
460
- log = pjoin (testdir , f"qa_{ wfname } " , "stdouterr.log" )
461
- cmd = [f"time cfchecks.py output_{ wfname } /{ wfname } .h5" ,
462
- f"""time verify_{ wfname } .py --fpdf qa_{ wfname } /graphs.pdf \
463
- --fhdf qa_{ wfname } /stats.h5 --flog qa_{ wfname } /qa.log --validate \
464
- --quality output_{ wfname } /{ wfname } .h5""" ]
511
+ os .makedirs (pjoin (testdir , f"qa_{ wfname } { suf } " ), exist_ok = True )
512
+ log = pjoin (testdir , f"qa_{ wfname } { suf } " , "stdouterr.log" )
513
+ # run qa command
514
+ cmd = [f"time cfchecks.py output_{ wfname } { suf } /{ wfname } .h5" ,
515
+ f"""time verify_{ wfname } .py --fpdf qa_{ wfname } { suf } /graphs.pdf \
516
+ --fhdf qa_{ wfname } { suf } /stats.h5 --flog qa_{ wfname } { suf } /qa.log --validate \
517
+ --quality output_{ wfname } { suf } /{ wfname } .h5""" ]
465
518
try :
466
519
self .distribrun (testdir , cmd , logfile = log , nisarimg = True ,
467
520
loghdlrname = f'wfqa.{ os .path .basename (testdir )} ' )
@@ -515,7 +568,7 @@ def insarqa(self, tests=None):
515
568
testdir = os .path .abspath (pjoin (self .testdir , testname ))
516
569
# run QA for each of the InSAR products
517
570
for product in ['rifg' , 'runw' , 'gunw' ]:
518
- print (f"\n Running workflow QA on InSAR test { testname } product { product .upper ()} \n " )
571
+ print (f"\n Running workflow QA on test { testname } { product .upper ()} product \n " )
519
572
qadir = pjoin (testdir , f"qa_{ product } " )
520
573
os .makedirs (qadir , exist_ok = True )
521
574
log = pjoin (qadir ,f"stdouterr.log" )
@@ -529,11 +582,27 @@ def insarqa(self, tests=None):
529
582
loghdlrname = f'wfqa.{ os .path .basename (testdir )} .{ product } ' )
530
583
except subprocess .CalledProcessError as e :
531
584
if product == 'gunw' :
532
- raise RuntimeError (f"Workflow QA on InSAR test { testname } product { product .upper ()} failed\n " ) from e
585
+ raise RuntimeError (f"Workflow QA on test { testname } { product .upper ()} product failed\n " ) from e
533
586
else :
534
587
# do not exit since CF checker errors are expected
535
- print (f"Found known errors running CF Checker on InSAR test { testname } product { product .upper ()} \n " )
536
-
588
+ print (f"Found known errors running CF Checker on test { testname } { product .upper ()} product\n " )
589
+
590
+ def end2endqa (self , tests = None ):
591
+ """
592
+ Run QA on all end2end workflow test results for one pair of L0B input data, including RSLC, GSLC, GCOV,
593
+ RIFG, RUNW, GUNW.
594
+
595
+ """
596
+ if tests is None :
597
+ tests = workflowtests ['end2end' ].items ()
598
+ for testname , dataname in tests :
599
+ for wfname in ['rslc' , 'gslc' , 'gcov' ]:
600
+ for suf , descr in [('_ref' , 'reference' ), ('_sec' , 'secondary' )]:
601
+ self .workflowqa (wfname , testname , suf = suf , description = f' { wfname .upper ()} { descr } product' )
602
+
603
+ self .insarqa ([testname ])
604
+
605
+
537
606
def minqa (self ):
538
607
"""
539
608
Only run qa for first test in each workflow
0 commit comments