Commits

Pam Ford authored 3c867cb1b94 Merge
Merge branch 'master' into CAS-13381

casatestutils/runtest.py

Modified
1 1 ########################################################################################################################
2 2 ############################################ Imports #############################################
3 3 ########################################################################################################################
4 -
5 4 import argparse
6 5 import os
7 6 import shutil
8 7 import sys
9 8 import traceback
10 9 import subprocess
11 10 import unittest
12 11 import json
13 12 import datetime
14 13 import platform
15 14
16 -
17 -default_timeout = 1800
18 -sys.path.insert(0,'')
19 -
20 15 ########################################################################################################################
21 16 ###################################### Imports / Constants #######################################
22 17 ########################################################################################################################
23 18
19 +default_timeout = 1800
20 +sys.path.insert(0,'')
21 +
24 22 # mem mode variables
25 23 HAVE_MEMTEST=True
26 24 MEM = 0
27 25 try:
28 26 import memTest
29 27 except ImportError:
30 28 HAVE_MEMTEST = False
31 29
32 30 # cov mode variables
33 31 HAVE_COVTEST=True
80 78
81 79 # Use Nose attribute Functionality
82 80 RUN_SUBTEST = False
83 81
84 82 # Dry run of Tests
85 83 DRY_RUN = False
86 84
87 85 ########################################################################################################################
88 86 ########################################### Functions ############################################
89 87 ########################################################################################################################
88 +# At the moment, this needs to be a sep function due to repr and escape characters, try/ except for osx
89 +def write_conftest_linux(filepath):
90 + string = """
91 +import pytest
92 +import inspect
93 +import os
94 +
95 +@pytest.mark.trylast
96 +def pytest_configure(config):
97 + terminal_reporter = config.pluginmanager.getplugin('terminalreporter')
98 + config.pluginmanager.register(TestDescriptionPlugin(terminal_reporter), 'testdescription')
99 +
100 +class TestDescriptionPlugin:
101 +
102 + def __init__(self, terminal_reporter):
103 + self.terminal_reporter = terminal_reporter
104 + self.desc = None
105 + self.funcn = None
106 +
107 + def pytest_runtest_protocol(self, item):
108 + #from pprint import pprint
109 + #d = item.__dict__
110 + #pprint(d, indent=2)
111 + self.desc = inspect.getdoc(item.obj)
112 + #print(item._nodeid)
113 + self.funcn = item._nodeid
114 +
115 + @pytest.hookimpl(hookwrapper=True, tryfirst=True)
116 + def pytest_runtest_logstart(self, nodeid, location):
117 + #print("Verbosity Level: {}".format(self.terminal_reporter.verbosity))
118 + if self.terminal_reporter.verbosity == 0:
119 + yield
120 + self.terminal_reporter.write(f'\\n{self.funcn} \\n')
121 + else:
122 + self.terminal_reporter.write('\\n')
123 + yield
124 + if self.desc:
125 + self.terminal_reporter.write(f'\\n{self.desc} \\n')
126 + else:
127 + self.terminal_reporter.write(f'\\n')
128 +
129 + @pytest.hookimpl(hookwrapper=True)
130 + def pytest_runtest_makereport(item, call):
131 + outcome = yield
132 + report = outcome.get_result()
133 + #print(dir(report))
134 + report.start = call.start
135 + report.stop = call.stop
136 + if report.when=='teardown':
137 + filepath = os.path.join(os.getcwd(),'short_summary.log')
138 +
139 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
140 + file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid,))
141 + file_obj.close()
142 +
143 + @pytest.hookimpl(hookwrapper=True)
144 + def pytest_runtest_makereport(item, call):
145 + outcome = yield
146 + report = outcome.get_result()
147 + if report.when=='call':
148 + filepath = os.path.join(os.getcwd(),'short_summary.log')
149 + # write short summary to file
150 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
151 + file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid))
152 + file_obj.close()
153 +
154 + # Write not pass to Textfile
155 + if report.outcome != 'passed':
156 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
157 + file_obj.write("\\tDuration: {}s\\n".format(round(report.duration,5)))
158 + file_obj.write("\\tMessage : {}\\n".format(report.longrepr.reprcrash.message))
159 + file_obj.close()
160 + filepath = os.path.join(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..')),'summary_of_failed.log')
161 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
162 + file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid))
163 + file_obj.write("\\tDuration: {}s\\n".format(round(report.duration,5)))
164 + file_obj.write("\\tMessage : {}\\n".format(report.longrepr.reprcrash.message))
165 + file_obj.close()
166 + """
167 + file_obj = open(filepath,'w')
168 + file_obj.write(string)
169 + file_obj.close()
170 +
171 +# At the moment, this needs to be a sep function due to repr and escape characters, try/ except for osx
172 +def write_conftest_osx(filepath):
173 + string = """
174 +import pytest
175 +import inspect
176 +import os
177 +
178 +@pytest.mark.trylast
179 +def pytest_configure(config):
180 + terminal_reporter = config.pluginmanager.getplugin('terminalreporter')
181 + try:
182 + config.pluginmanager.unregister(TestDescriptionPlugin(terminal_reporter), 'testdescription')
183 + except:
184 + pass
185 + config.pluginmanager.register(TestDescriptionPlugin(terminal_reporter), 'testdescription')
186 +
187 +class TestDescriptionPlugin:
188 +
189 + def __init__(self, terminal_reporter):
190 + self.terminal_reporter = terminal_reporter
191 + self.desc = None
192 + self.funcn = None
193 +
194 + def pytest_runtest_protocol(self, item):
195 + #from pprint import pprint
196 + #d = item.__dict__
197 + #pprint(d, indent=2)
198 + self.desc = inspect.getdoc(item.obj)
199 + #print(item._nodeid)
200 + self.funcn = item._nodeid
201 +
202 + @pytest.hookimpl(hookwrapper=True, tryfirst=True)
203 + def pytest_runtest_logstart(self, nodeid, location):
204 + #print("Verbosity Level: {}".format(self.terminal_reporter.verbosity))
205 + if self.terminal_reporter.verbosity == 0:
206 + yield
207 + self.terminal_reporter.write(f'\\n{self.funcn} \\n')
208 + else:
209 + self.terminal_reporter.write('\\n')
210 + yield
211 + if self.desc:
212 + self.terminal_reporter.write(f'\\n{self.desc} \\n')
213 + else:
214 + self.terminal_reporter.write(f'\\n')
215 +
216 + @pytest.hookimpl(hookwrapper=True)
217 + def pytest_runtest_makereport(item, call):
218 + outcome = yield
219 + report = outcome.get_result()
220 + if report.when=='call':
221 + filepath = os.path.join(os.getcwd(),'short_summary.log')
222 + # write short summary to file
223 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
224 + file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid))
225 + file_obj.close()
226 +
227 + # Write not pass to Textfile
228 + if report.outcome != 'passed':
229 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
230 + file_obj.write("\\tDuration: {}s\\n".format(round(report.duration,5)))
231 + file_obj.write("\\tMessage : {}\\n".format(report.longrepr.reprcrash.message))
232 + file_obj.close()
233 + filepath = os.path.join(os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..')),'summary_of_failed.log')
234 + file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w')
235 + file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid))
236 + file_obj.write("\\tDuration: {}s\\n".format(round(report.duration,5)))
237 + file_obj.write("\\tMessage : {}\\n".format(report.longrepr.reprcrash.message))
238 + file_obj.close()
239 + """
240 + file_obj = open(filepath,'w')
241 + file_obj.write(string)
242 + file_obj.close()
90 243
91 244 class casa_test:
92 245 def __init__(self,
93 246 name,
94 247 path,
95 248 test_group=None,
96 249 test_type=None,
97 250 maintainer=None,
98 251 email=None,
99 252 options=None,
239 392 ## Almatasks
240 393
241 394 os.chdir(os.path.dirname(os.getcwd()))
242 395 os.makedirs("almatasks")
243 396 os.chdir("almatasks")
244 397 subprocess.call(["git","init", "--quiet"])
245 398 subprocess.call(["git","remote","add","-f","origin", "https://open-bitbucket.nrao.edu/scm/casa/almatasks.git"], stdout=FNULL, stderr=subprocess.STDOUT)
246 399 subprocess.call(["git","config","core.sparseCheckout","true"])
247 400 print("tests/tasks", file=open(".git/info/sparse-checkout", "a"))
248 401 subprocess.call(['git','pull','--quiet','origin','master'])
402 +
403 + ## casaviewer
404 +
249 405 os.chdir(os.path.dirname(os.getcwd()))
406 + os.makedirs("casaviewer")
407 + os.chdir("casaviewer")
408 + subprocess.call(["git","init", "--quiet"])
409 + subprocess.call(["git","remote","add","-f","origin", "https://open-bitbucket.nrao.edu/scm/casa/casaviewer.git"], stdout=FNULL, stderr=subprocess.STDOUT)
410 + subprocess.call(["git","config","core.sparseCheckout","true"])
411 + print("tests/tasks", file=open(".git/info/sparse-checkout", "a"))
412 + subprocess.call(['git','pull','--quiet','origin','master'])
250 413
414 + ## casampi
251 415
416 + os.chdir(os.path.dirname(os.getcwd()))
417 + os.makedirs("casampi")
418 + os.chdir("casampi")
419 + subprocess.call(["git","init", "--quiet"])
420 + subprocess.call(["git","remote","add","-f","origin", "https://open-bitbucket.nrao.edu/scm/casa/casampi.git"], stdout=FNULL, stderr=subprocess.STDOUT)
421 + subprocess.call(["git","config","core.sparseCheckout","true"])
422 + print("src/casampi/tests", file=open(".git/info/sparse-checkout", "a"))
423 + subprocess.call(['git','pull','--quiet','origin','master'])
424 +
425 + os.chdir(os.path.dirname(os.getcwd()))
252 426 os.chdir(cwd)
253 427
254 428 def git_fetch_casa_tests_branch(path, branch):
255 429
256 430 cwd = os.getcwd()
257 431 if os.path.exists(path):
258 432 try:
259 433 os.rmdir(path)
260 434 except:
261 435 shutil.rmtree(path)
450 624 # Copy Tests to Working Directory
451 625 os.makedirs(workdir)
452 626
453 627 if RUN_ALL:
454 628 print("Gathering All Tests")
455 629 git_fetch_casa_tests( workpath + 'casa6')
456 630 os.makedirs(workdir + "all/")
457 631 gather_all_tests(workpath +'casa6/', workdir + "all/")
458 632 gather_all_tests(workpath +'casaplotms/', workdir + "all/")
459 633 gather_all_tests(workpath +'almatasks/', workdir + "all/")
634 + gather_all_tests(workpath +'casaviewer/', workdir + "all/")
635 + gather_all_tests(workpath +'casampi/', workdir + "all/")
460 636 cmd = [ workdir ]
461 637 cmd = ["--continue-on-collection-errors"] + cmd
462 - if verbose:
463 - cmd = ["--verbose"] + cmd
638 + cmd = ["--verbose"] + ["-ra"] + cmd
464 639
465 640
466 641 if DRY_RUN:
467 642 cmd = ["--collect-only"] + cmd
468 643
469 644 if not os.path.isdir(workpath + '/xml/all/'):
470 645 os.makedirs(workpath + '/xml/all/')
471 646 xmlfile = workpath + '/xml/all/nose.xml'
472 647
473 648 #########
477 652 # PytestDeprecationWarning: The 'junit_family' # default value will change to 'xunit2' in pytest 6.0.
478 653 # Add 'junit_family=xunit1' to your pytest.ini file to keep the current format in future versions of pytest and silence this warning.
479 654 # _issue_warning_captured(deprecated.JUNIT_XML_DEFAULT_FAMILY, config.hook, 2)
480 655 #########
481 656 cmd = ["--junitxml={}".format(xmlfile)] + ["-s"] + cmd
482 657
483 658 if len(os.listdir(workdir + "all/")) == 0:
484 659 print("No Tests to Run")
485 660 else:
486 661 print("Running Command: pytest {}".format(cmd))
662 + conf_name = os.path.join(os.getcwd(),"conftest.py")
663 + if platform.system() == 'Darwin':
664 + write_conftest_osx(conf_name)
665 + else:
666 + write_conftest_linux(conf_name)
487 667 pytest.main(cmd)
668 + os.remove(conf_name)
488 669
489 670 else:
490 671 print("Tests: {}".format(testnames))
491 672 gittest = True
492 673
493 674 for testname in testnames:
494 675 cmd = []
495 676
496 677 # Copy Test To nosedir Directory if in cwd
497 678 if testname.startswith("test"):
533 714 # gather_all_tests(workpath +'almatasks/', workdir + "tests/")
534 715 gittest = False
535 716
536 717 else:
537 718 print("Fetching Tests From Git Main Since No Local Test is Given")
538 719 git_fetch_casa_tests( workpath + 'casa6/')
539 720 os.makedirs(workdir + "tests/")
540 721 gather_all_tests(workpath +'casa6/', workdir + "tests/")
541 722 gather_all_tests(workpath +'casaplotms/', workdir + "tests/")
542 723 gather_all_tests(workpath +'almatasks/', workdir + "tests/")
724 + gather_all_tests(workpath +'casaviewer/', workdir + "tests/")
725 + gather_all_tests(workpath +'casampi/', workdir + "tests/")
543 726 gittest = False
544 727
545 728 if test.endswith(".py"):
546 729 try:
547 730 print("Copying: {} to {}".format(test, workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])))
548 731 shutil.copy2(test, workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))
549 732 except:
550 733 traceback.print_exc()
551 734 else:
552 735 try:
553 736 print("Copying: {} to {}".format(workdir + "tests/",test), workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))
554 737 shutil.copy2("{}{}.py".format(workdir + "tests/",test), workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))
555 738 except:
556 739 traceback.print_exc()
557 740
558 741 # https://docs.pytest.org/en/stable/usage.html
559 - if verbose:
560 - cmd = ["--verbose"] + ["--tb=long"] + cmd
561 - elif not verbose:
562 - cmd = ["-ra"] + ["--tb=short"] + cmd
563 - #cmd = ["-ra"] + ["--tb=long"] + cmd
742 +
743 + cmd = ["--verbose"] + ["-ra"] + ["--tb=short"] + cmd
564 744
565 745 if DRY_RUN:
566 746 cmd = ["--collect-only"] + cmd
567 747
568 748 if not os.path.isdir(workpath + '/xml/{}/'.format(test if not test.endswith(".py") else test[:-3])):
569 749 os.makedirs(workpath + '/xml/{}/'.format(test if not test.endswith(".py") else test[:-3]))
570 750 xmlfile = workpath + 'xml/{}/nose.xml'.format(test if not test.endswith(".py") else test[:-3])
571 751
572 752 #########
573 753 #============================================================ warnings summary =====================================================
582 762 #print("Work Path: {}".format(workpath))
583 763 if len(os.listdir(workpath)) < 1: # If only the XML dir was created
584 764 print("No Tests to Run")
585 765 sys.exit()
586 766 else:
587 767
588 768 myworkdir = os.getcwd()
589 769 os.chdir("{}".format(workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])))
590 770 print("Test Directory: {}".format(os.getcwd()))
591 771 print("Running Command: pytest {}".format(cmd))
772 + conf_name = os.path.join(os.getcwd(),"conftest.py")
773 + if platform.system() == 'Darwin':
774 + write_conftest_osx(conf_name)
775 + else:
776 + write_conftest_linux(conf_name)
592 777 pytest.main(cmd)
778 + os.remove(conf_name)
593 779 os.chdir(myworkdir)
594 780
595 781 ##################################################
596 782 ########## Real Path ##########
597 783 ##################################################
598 784 # Copy Test To nosedir Directory assuming it's in another location
599 785 elif testname.startswith("/"):
600 786 testpath = testname.split("[")[0]
601 787 cmd = []
602 788 dirname = testname.split("/")[-1]
626 812 # Set up Test Working Directory
627 813 if not os.path.exists(workdir + "{}/".format(dirname)):
628 814 print("Setting Working Directory: {}".format(workdir + "{}/".format(dirname)))
629 815 os.makedirs(workdir + "{}/".format(dirname))
630 816 cmd = [ workdir + "{}/".format(dirname) ] + cmd
631 817 try:
632 818 shutil.copy2(testpath, workdir + "{}/".format(dirname))
633 819 except:
634 820 traceback.print_exc()
635 821
636 - if verbose:
637 - cmd = ["--verbose"] + ["--tb=long"] + cmd
638 - elif not verbose:
639 - cmd = ["-ra"] + ["--tb=short"] + cmd
640 - #cmd = ["-ra"] + ["--tb=long"] + cmd
641 -
822 + cmd = ["--verbose"] + ["-ra"] + ["--tb=short"] + cmd
642 823
643 824 if DRY_RUN:
644 825 cmd = ["--collect-only"] + cmd
645 826
646 827 if not os.path.isdir(workpath + '/xml/{}/'.format(dirname)):
647 828 os.makedirs(workpath + '/xml/{}/'.format(dirname))
648 829 xmlfile = workpath + 'xml/{}/nose.xml'.format(dirname)
649 830
650 831 #########
651 832 #============================================================ warnings summary =====================================================
659 840 #print("Running Command: pytest {}".format(cmd))
660 841 #print("Work Path: {}".format(workpath))
661 842 if len(os.listdir(workpath)) < 1: # If only the XML dir was created
662 843 print("No Tests to Run")
663 844 sys.exit()
664 845 else:
665 846 myworkdir = os.getcwd()
666 847 os.chdir(workdir + "{}/".format(dirname))
667 848 print("Test Directory: {}".format(os.getcwd()))
668 849 print("Running Command: pytest {}".format(cmd))
850 + conf_name = os.path.join(os.getcwd(),"conftest.py")
851 + if platform.system() == 'Darwin':
852 + write_conftest_osx(conf_name)
853 + else:
854 + write_conftest_linux(conf_name)
669 855 pytest.main(cmd)
856 + os.remove(conf_name)
670 857 os.chdir(myworkdir)
671 858 os.chdir(cwd)
672 859
673 860 if not HAVE_PYTEST:
674 861 print("Missing Pytest")
675 862
676 863
677 864 ########################################################################################################################
678 865 ####################################### Run Bamboo Option ########################################
679 866 ########################################################################################################################

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut