2424# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525# SOFTWARE.
2626# ------------------------------------------------------------------------------
27- """Implementation of juliet commands in the command-line interpreter ."""
27+ """Implementation of juliet commands in the CLI ."""
2828
2929import argparse
3030import json
3838from multiprocessing import Pool
3939
4040from typing import (
41- Any , Callable , Dict , List , NoReturn , Optional , Tuple , TYPE_CHECKING )
41+ Any , Callable , cast , Dict , List , NoReturn , Optional , Tuple , TYPE_CHECKING )
4242
4343from chc .app .CApplication import CApplication
4444
@@ -382,7 +382,7 @@ def save_xrefs(f: "CFile") -> None:
382382 am .generate_and_check_app ("llrvisp" , processes = jmaxproc )
383383 capp .reinitialize_tables ()
384384
385- def filefilter (filename ) :
385+ def filefilter (filename : str ) -> bool :
386386 return not (filename in ["io" , "main_linux" , "std_thread" ])
387387
388388 contractviolations = capp .get_contract_condition_violations ()
@@ -403,7 +403,7 @@ def filefilter(filename):
403403 exit (0 )
404404
405405
406- def analyze_test (testdata ) :
406+ def analyze_test (testdata : Tuple [ str , str , int ]) -> int :
407407 """CLI command to run a juliet test case.
408408
409409 Note: this function needs to be global for multiprocessing to work.
@@ -427,7 +427,7 @@ def juliet_analyze_sets(args: argparse.Namespace) -> NoReturn:
427427 pool = Pool (jmaxproc )
428428 testcases = []
429429
430- def excluded (cwe ) :
430+ def excluded (cwe : str ) -> bool :
431431 if len (jcwes ) == 0 :
432432 return False
433433 else :
@@ -616,6 +616,61 @@ def juliet_score(args: argparse.Namespace) -> NoReturn:
616616 exit (0 )
617617
618618
619+ def score_test (testdata : Tuple [str , str , int ]) -> int :
620+ """CLI command to score a juliet test case.
621+
622+ Note: this function needs to be global for multiprocessing to work.
623+ """
624+
625+ (cwe , testcase , index ) = testdata
626+ cmd = ["chkc" , "juliet" , "score" , cwe , testcase ]
627+ result = subprocess .call (cmd , stderr = subprocess .STDOUT )
628+ return result
629+
630+
631+ def juliet_score_sets (args : argparse .Namespace ) -> NoReturn :
632+ """Scores all or a subset of the registered juliet tests."""
633+
634+ # arguments
635+ jmaxproc : int = args .maxprocesses
636+ jcwes : List [str ] = args .cwes
637+
638+ maxptxt = "" if jmaxproc == 1 else f" (with { jmaxproc } processors)"
639+
640+ pool = Pool (jmaxproc )
641+ testcases = []
642+
643+ def excluded (cwe : str ) -> bool :
644+ if len (jcwes ) == 0 :
645+ return False
646+ else :
647+ return cwe not in jcwes
648+
649+ with timing ("score-sets" + maxptxt ):
650+ count : int = 0
651+ juliettests = UF .get_juliet_testcases ()
652+ for cwe in sorted (juliettests ):
653+ if excluded (cwe ):
654+ continue
655+ print (f"Scoring testcases for cwe { cwe } " )
656+ for subdir in sorted (juliettests [cwe ]):
657+ for t in juliettests [cwe ][subdir ]:
658+ testcases .append ((cwe , t , count ))
659+
660+ results = pool .map (score_test , testcases )
661+
662+ print ("\n " + ("=" * 80 ))
663+ if len (results ) == results .count (0 ):
664+ print ("All Juliet tests cases were scored successfully." )
665+ else :
666+ for x in range (len (results )):
667+ if results [x ] != 0 :
668+ print (f"Error in testcase { testcases [x ][0 ]} " )
669+ print ("=" * 80 )
670+
671+ exit (0 )
672+
673+
619674def juliet_investigate (args : argparse .Namespace ) -> NoReturn :
620675 """Lists problematic proof obligations."""
621676
@@ -978,8 +1033,10 @@ def juliet_project_dashboard(args: argparse.Namespace) -> NoReturn:
9781033 spo_project_totals [pname ] = {}
9791034
9801035 if "stats" in results :
981- projectstats [pname ] = results ["stats" ]
982- analysistimes [pname ] = results ["timestamp" ]
1036+ # use casts to handle union type in loaded dictionary
1037+ projectstats [pname ] = cast (
1038+ Tuple [int , int , int ], results ["stats" ])
1039+ analysistimes [pname ] = cast (int , results ["timestamp" ])
9831040 else :
9841041 projectstats [pname ] = (0 , 0 , 0 )
9851042
0 commit comments