Commits
Akeem Wells authored and Ville Suoranta committed 04e8dac5299 Merge
1 1 | ######################################################################################################################## |
2 2 | ############################################ Imports ############################################# |
3 3 | ######################################################################################################################## |
4 - | import argparse |
5 - | import os |
6 - | import shutil |
7 - | import sys |
8 - | import traceback |
9 - | import subprocess |
10 - | import unittest |
11 - | import json |
12 - | import datetime |
13 - | import platform |
14 - | import re |
15 - | import shlex |
16 4 | |
17 - | ######################################################################################################################## |
18 - | ###################################### Imports / Constants ####################################### |
19 - | ######################################################################################################################## |
5 + | import os, sys, re, json, unittest, shlex |
6 + | import argparse, subprocess, traceback |
7 + | import shutil, datetime, platform |
20 8 | |
21 9 | default_timeout = 1800 |
22 10 | sys.path.insert(0,'') |
23 11 | |
24 - | # cov mode variables |
25 - | HAVE_COVTEST=True |
26 - | COV = 0 |
27 - | try: |
28 - | import coverage |
29 - | except ImportError: |
30 - | HAVE_COVTEST = False |
31 - | |
32 - | # pybot mode variables |
33 - | |
34 - | USE_PYBOT = 0 |
35 - | |
36 12 | #### PYTEST IMPORT |
37 13 | HAVE_PYTEST = True |
38 14 | try: |
39 15 | import pytest |
40 16 | except ImportError: |
41 17 | HAVE_PYTEST = False |
42 18 | |
43 19 | verbose = False |
44 20 | |
45 21 | # JIRA BRANCH TO CHECKOUT |
46 22 | JIRA_BRANCH = None |
47 23 | |
48 24 | # Dry run of Tests |
49 25 | DRY_RUN = False |
50 26 | |
51 27 | ######################################################################################################################## |
52 28 | ########################################### Functions ############################################ |
53 29 | ######################################################################################################################## |
54 30 | # At the moment, this needs to be a sep function due to repr and escape characters, try/ except for osx |
55 - | def write_conftest_linux(filepath): |
31 + | def write_conftest_osx(filepath): |
56 32 | string = """ |
57 33 | import pytest |
58 34 | import inspect |
59 35 | import os |
60 36 | |
61 37 | @pytest.mark.trylast |
62 38 | def pytest_configure(config): |
63 39 | terminal_reporter = config.pluginmanager.getplugin('terminalreporter') |
40 + | try: |
41 + | config.pluginmanager.unregister(TestDescriptionPlugin(terminal_reporter), 'testdescription') |
42 + | except: |
43 + | pass |
64 44 | config.pluginmanager.register(TestDescriptionPlugin(terminal_reporter), 'testdescription') |
65 45 | |
66 46 | class TestDescriptionPlugin: |
67 47 | |
68 48 | def __init__(self, terminal_reporter): |
69 49 | self.terminal_reporter = terminal_reporter |
70 50 | self.desc = None |
71 51 | self.funcn = None |
72 52 | |
73 53 | def pytest_runtest_protocol(self, item): |
85 65 | yield |
86 66 | self.terminal_reporter.write(f'\\n{self.funcn} \\n') |
87 67 | else: |
88 68 | self.terminal_reporter.write('\\n') |
89 69 | yield |
90 70 | if self.desc: |
91 71 | self.terminal_reporter.write(f'\\n{self.desc} \\n') |
92 72 | else: |
93 73 | self.terminal_reporter.write(f'\\n') |
94 74 | |
95 - | @pytest.hookimpl(hookwrapper=True) |
96 - | def pytest_runtest_makereport(item, call): |
97 - | outcome = yield |
98 - | report = outcome.get_result() |
99 - | #print(dir(report)) |
100 - | report.start = call.start |
101 - | report.stop = call.stop |
102 - | if report.when=='teardown': |
103 - | filepath = os.path.join(os.getcwd(),'short_summary.log') |
104 - | |
105 - | file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w') |
106 - | file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid,)) |
107 - | file_obj.close() |
108 - | |
109 75 | @pytest.hookimpl(hookwrapper=True) |
110 76 | def pytest_runtest_makereport(item, call): |
111 77 | outcome = yield |
112 78 | report = outcome.get_result() |
113 79 | if report.when=='call': |
114 80 | filepath = os.path.join(os.getcwd(),'short_summary.log') |
115 81 | # write short summary to file |
116 82 | file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w') |
117 83 | file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid)) |
118 84 | file_obj.close() |
129 95 | file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid)) |
130 96 | file_obj.write("\\tDuration: {}s\\n".format(round(report.duration,5))) |
131 97 | if report.outcome == 'failed': |
132 98 | file_obj.write("\\tMessage : {}\\n".format(report.longrepr.reprcrash.message)) |
133 99 | file_obj.close() |
134 100 | """ |
135 101 | file_obj = open(filepath,'w') |
136 102 | file_obj.write(string) |
137 103 | file_obj.close() |
138 104 | |
139 - | # At the moment, this needs to be a sep function due to repr and escape characters, try/ except for osx |
140 - | def write_conftest_osx(filepath): |
105 + | def write_conftest_linux(filepath): |
141 106 | string = """ |
142 107 | import pytest |
143 108 | import inspect |
144 109 | import os |
145 110 | |
146 111 | @pytest.mark.trylast |
147 112 | def pytest_configure(config): |
148 113 | terminal_reporter = config.pluginmanager.getplugin('terminalreporter') |
149 - | try: |
150 - | config.pluginmanager.unregister(TestDescriptionPlugin(terminal_reporter), 'testdescription') |
151 - | except: |
152 - | pass |
153 114 | config.pluginmanager.register(TestDescriptionPlugin(terminal_reporter), 'testdescription') |
154 115 | |
155 116 | class TestDescriptionPlugin: |
156 117 | |
157 118 | def __init__(self, terminal_reporter): |
158 119 | self.terminal_reporter = terminal_reporter |
159 120 | self.desc = None |
160 121 | self.funcn = None |
161 122 | |
162 123 | def pytest_runtest_protocol(self, item): |
174 135 | yield |
175 136 | self.terminal_reporter.write(f'\\n{self.funcn} \\n') |
176 137 | else: |
177 138 | self.terminal_reporter.write('\\n') |
178 139 | yield |
179 140 | if self.desc: |
180 141 | self.terminal_reporter.write(f'\\n{self.desc} \\n') |
181 142 | else: |
182 143 | self.terminal_reporter.write(f'\\n') |
183 144 | |
145 + | @pytest.hookimpl(hookwrapper=True) |
146 + | def pytest_runtest_makereport(item, call): |
147 + | outcome = yield |
148 + | report = outcome.get_result() |
149 + | #print(dir(report)) |
150 + | report.start = call.start |
151 + | report.stop = call.stop |
152 + | if report.when=='teardown': |
153 + | filepath = os.path.join(os.getcwd(),'short_summary.log') |
154 + | |
155 + | file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w') |
156 + | file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid,)) |
157 + | file_obj.close() |
158 + | |
184 159 | @pytest.hookimpl(hookwrapper=True) |
185 160 | def pytest_runtest_makereport(item, call): |
186 161 | outcome = yield |
187 162 | report = outcome.get_result() |
188 163 | if report.when=='call': |
189 164 | filepath = os.path.join(os.getcwd(),'short_summary.log') |
190 165 | # write short summary to file |
191 166 | file_obj = open(filepath, 'a' if os.path.isfile(filepath) else 'w') |
192 167 | file_obj.write("{} {}\\n".format(report.outcome.upper(), report.nodeid)) |
193 168 | file_obj.close() |
214 189 | def write_pytestini(filepath, testname): |
215 190 | string = """ |
216 191 | [pytest] |
217 192 | junit_suite_name = '{}' |
218 193 | """.format(testname) |
219 194 | |
220 195 | file_obj = open(filepath,'w') |
221 196 | file_obj.write(string) |
222 197 | file_obj.close() |
223 198 | |
199 + | def clean_working_directory(workdir): |
200 + | print("Cleaning: {}".format(workdir)) |
201 + | if os.path.exists(workdir): |
202 + | shutil.rmtree(workdir) |
203 + | |
204 + | def list_tests(local_path): |
205 + | print('Full list of unit tests') |
206 + | print('-----------------------') |
207 + | if os.path.isdir(local_path +"/testlist/"): |
208 + | shutil.rmtree(local_path +"/testlist/") |
209 + | os.makedirs(local_path +"/testlist/") |
210 + | testpaths = fetch_tests(local_path +"/testlist/", 'master') |
211 + | for path in testpaths: |
212 + | gather_all_tests(path, local_path +"/testlist/") |
213 + | tests = sorted(os.listdir(local_path +"/testlist/")) |
214 + | for test in tests: |
215 + | if test.startswith("test_"): |
216 + | print(test) |
217 + | |
218 + | def gather_all_tests(path, workpath): |
219 + | |
220 + | if sys.version_info[0] > 2: |
221 + | import pathlib |
222 + | for filename in pathlib.Path(path).rglob('test_*.py'): |
223 + | shutil.copy2(filename, workpath) |
224 + | |
225 + | def gettests(testfile): |
226 + | '''Get the list of specific tests from the command-line |
227 + | Ex: from test_clean[test1,test3] returns [test1,test3]''' |
228 + | n0 = testfile.rfind('[') |
229 + | n1 = testfile.rfind(']') |
230 + | if n0 != -1: |
231 + | temp = testfile[n0+1:n1] |
232 + | tests = temp.split(',') |
233 + | return tests |
234 + | |
235 + | def getname(testfile): |
236 + | '''Get the test name from the command-line |
237 + | Ex: from test_clean[test1], returns test_clean''' |
238 + | n0 = testfile.rfind('[') |
239 + | n1 = testfile.rfind(']') |
240 + | if n0 != -1: |
241 + | return testfile[:n0] |
242 + | |
224 243 | def update_xml(filename): |
225 244 | import xml.etree.ElementTree as ET |
226 245 | xmlTree = ET.parse(filename) |
227 246 | rootElement = xmlTree.getroot() |
228 247 | for element in rootElement.iter(): |
229 248 | if element.tag == 'testcase': |
230 249 | testname = element.attrib['name'] |
231 250 | testscript = element.attrib['classname'].split(".")[0] |
232 251 | testclass = element.attrib['classname'].split(".")[1] |
233 252 | #print(name,testscript,testclass) |
234 253 | element.set("classname",testscript) |
235 254 | element.set("name",'.'.join([testclass,testname])) |
236 - | xmlTree.write(filename,encoding='UTF-8',xml_declaration=True) |
255 + | xmlTree.write(filename,encoding='UTF-8',xml_declaration=True) |
237 256 | |
238 257 | class casa_test: |
239 258 | def __init__(self, |
240 259 | name, |
241 260 | path, |
242 261 | test_group=None, |
243 262 | test_type=None, |
244 263 | maintainer=None, |
245 264 | email=None, |
246 265 | options=None, |
268 287 | def read_conf(conf): |
269 288 | with open(conf) as f: |
270 289 | lines = [line.rstrip() for line in f] |
271 290 | outDict = dict(x.split('==') for x in lines) |
272 291 | for key in list(outDict.keys()): |
273 292 | if ".dev" in outDict[key]: |
274 293 | tag = re.findall(r"a([\s\S]*)$",outDict[key])[0] |
275 294 | outDict[key] = "CAS-" + tag.replace(".dev","-") |
276 295 | return outDict |
277 296 | |
278 - | def fetch_tests(work_dir, branch): |
297 + | def run_shell_command(cmd, run_directory): |
298 + | try: |
299 + | r = ShellRunner() |
300 + | r.runshell(cmd, default_timeout, run_directory) |
301 + | except: |
302 + | cwd = os.getcwd() |
303 + | os.chdir(run_directory) |
304 + | subprocess.call(cmd, stdout = subprocess.DEVNULL, stderr=subprocess.STDOUT) |
305 + | os.chdir(cwd) |
306 + | |
307 + | def is_in_remote(branch,repo_path, repo): |
308 + | if branch != 'master': |
309 + | cmd = 'git ls-remote --heads {}{} {} | wc -l'.format(repo_path, repo, branch ) |
310 + | #print("\tRunning: ", cmd) |
311 + | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell = True) |
312 + | out = proc.stdout.read() |
313 + | if int(out)== 0: # If Feature Branch Exists Does Not exist, revert to master |
314 + | return False |
315 + | else: |
316 + | return True |
317 + | else: |
318 + | return True |
319 + | |
320 + | def fetch_tests(work_dir, branch, merge_target=None): |
321 + | |
322 + | if merge_target is not None: |
323 + | print("Merge Target Enabled: \n\tTarget Branch: {} \n\tFeature Branch: {}".format(merge_target, branch)) |
279 324 | |
280 325 | repo_path = "https://open-bitbucket.nrao.edu/scm/casa/" |
281 - | |
326 + | source_dir = work_dir + "/casasources" |
282 327 | # Test if https is restricted |
283 328 | p1 = subprocess.Popen(shlex.split("curl -k -X GET https://open-bitbucket.nrao.edu/rest/api/1.0/projects/CASA/repos/casa6"), stdout=subprocess.PIPE) |
284 329 | p2 = subprocess.Popen(shlex.split('grep "not permitted"'), stdin=p1.stdout) |
285 330 | p2.communicate() |
286 331 | if (p2.returncode == 0): |
287 332 | repo_path = "ssh://git@open-bitbucket.nrao.edu:7999/casa/" |
288 - | |
289 - | source_dir=work_dir + "/casasources" |
290 333 | if not os.path.exists(source_dir): |
291 334 | os.makedirs(source_dir) |
292 - | repositories = ["casa6", "casampi", "casaplotms", "almatasks","casaviewer"] |
335 + | |
293 336 | # All of the repositositories have their tests in different directories |
294 337 | # so we need a mapping |
295 338 | def get_repo_test_paths(x): |
296 339 | return { |
297 340 | "casa6": ["/casa6/casatests/regression/","/casa6/casatests/stakeholder/","/casa6/casatasks/tests/","/casa6/casatools/tests/"], |
298 341 | "casampi": ["/casampi/src/casampi/tests"], |
299 342 | "casaplotms": ["/casaplotms/tests/plotms"], |
300 343 | "almatasks": ["/almatasks/tests/tasks"], |
301 344 | "casaviewer": ["/casaviewer/tests/tasks"] |
302 345 | }[x] |
303 346 | |
304 - | # Clone the repository and checkout branch |
305 - | for repo in repositories: |
306 - | cmd = ("git clone " + repo_path + repo).split() |
307 - | print("Running: ", " ".join(str(x) for x in cmd)) |
308 - | try: |
309 - | r = ShellRunner() |
310 - | r.runshell(cmd, default_timeout, source_dir) |
311 - | except: |
312 - | cwd = os.getcwd() |
313 - | os.chdir(source_dir) |
314 - | subprocess.call(cmd, stdout = subprocess.DEVNULL, stderr=subprocess.STDOUT) |
315 - | os.chdir(cwd) |
316 - | if branch != 'master' and repo != 'casa6': |
317 - | cmd = 'git ls-remote --heads {}{} {} | wc -l'.format(repo_path, repo, branch ) |
318 - | #print(cmd) |
319 - | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell = True) |
320 - | out = proc.stdout.read() |
321 - | if int(out)== 0: |
322 - | if repo in ['casaplotserver', 'casaplotms','casaviewer','casampi','almatasks','casatelemetry']: |
323 - | print("build.conf location: " + source_dir + "/casa6/build.conf" ) |
324 - | branchtag = "tags/{}".format(read_conf(source_dir+"/casa6/build.conf")[repo]) |
325 - | print("branchtag" + branchtag) |
326 - | cmd = ("git checkout " + branchtag).split() |
327 - | else: |
328 - | cmd = ("git checkout " + branch).split() |
329 - | elif branch == 'master' and repo != 'casa6' and os.path.isfile(source_dir+"/casa6/build.conf"): |
330 - | if repo in ['casaplotserver', 'casaplotms','casaviewer','casampi','almatasks','casatelemetry']: |
331 - | branchtag = "tags/{}".format(read_conf(source_dir+"/casa6/build.conf")[repo]) |
332 - | cmd = ("git checkout " + branchtag).split() |
333 - | else: |
334 - | cmd = ("git checkout " + branch).split() |
335 - | print(cmd) |
336 - | try: |
337 - | r = ShellRunner() |
338 - | r.runshell(cmd, default_timeout, source_dir + "/" + repo) |
339 - | except: |
340 - | cwd = os.getcwd() |
341 - | os.chdir(source_dir + "/" + repo) |
342 - | subprocess.call(cmd, stdout = subprocess.DEVNULL, stderr=subprocess.STDOUT) |
343 - | os.chdir(cwd) |
344 - | for x in get_repo_test_paths(repo): |
345 - | test_paths.append(source_dir + "/" + x) |
346 - | return test_paths |
347 - | |
348 - | def readfile(FILE): |
349 - | # It will skip lines that contain '#' and |
350 - | # it will only read words starting with test |
351 - | if(not os.path.exists(FILE)): |
352 - | print('ERROR: List of tests does not exist') |
353 - | return [] |
354 - | |
355 - | List = [] |
356 - | infile = open(FILE, "r") |
357 - | for newline in infile: |
358 - | if newline.__contains__('#'): |
359 - | continue |
360 - | |
361 - | if newline.startswith('test'): |
362 - | words = newline.split() |
363 - | List.append(words[0]) |
347 + | # Fetch CASA6 Repo First as Base |
348 + | repo = "casa6" |
349 + | print("Fetching Repository: {}".format(repo)) |
350 + | cmd = ("git clone " + repo_path + repo).split() |
351 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
352 + | run_shell_command(cmd, source_dir) |
364 353 | |
365 - | infile.close() |
366 - | return List |
354 + | if merge_target is not None: |
367 355 | |
368 - | def list_tests(): |
369 - | print('Full list of unit tests') |
370 - | print('-----------------------') |
371 - | if os.path.isdir(os.getcwd() +"/testlist/"): |
372 - | shutil.rmtree(os.getcwd() +"/testlist/") |
373 - | os.makedirs(os.getcwd() +"/testlist/") |
374 - | testpaths = fetch_tests(os.getcwd() +"/testlist/", 'master') |
375 - | for path in testpaths: |
376 - | gather_all_tests(path, os.getcwd() +"/testlist/") |
377 - | tests = sorted(os.listdir(os.getcwd() +"/testlist/")) |
378 - | for test in tests: |
379 - | if test.startswith("test_"): |
380 - | print(test) |
356 + | cmd = ("git checkout " + merge_target).split() |
357 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
358 + | run_shell_command(cmd, source_dir + "/" + repo) |
381 359 | |
360 + | if is_in_remote(branch,repo_path, repo): # Test if the branch is in the remote repository |
361 + | print("\tMerging {} into {}".format(branch, merge_target)) |
362 + | cmd = ("git merge " + branch).split() |
363 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
364 + | run_shell_command(cmd, source_dir + "/" + repo) |
365 + | else: |
366 + | print("\t{} not in Remote Repository {}".format(branch,repo)) |
367 + | else: |
368 + | cmd = ("git checkout " + branch).split() |
369 + | if is_in_remote(branch,repo_path, repo): |
370 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
371 + | else: |
372 + | print("\t{} not in Remote Repository {}. Defaulting to master".format(branch,repo)) |
373 + | run_shell_command(cmd, source_dir + "/" + repo) |
382 374 | |
383 - | def gather_all_tests(path, workpath): |
375 + | for x in get_repo_test_paths(repo): |
376 + | test_paths.append(source_dir + "/" + x) |
384 377 | |
385 - | if sys.version_info[0] > 2: |
386 - | import pathlib |
387 - | for filename in pathlib.Path(path).rglob('test_*.py'): |
388 - | #print(filename) |
389 - | shutil.copy2(filename, workpath) |
378 + | # Clone the auxiliary repositories and checkout branch |
379 + | repositories = ["casampi", "casaplotms", "almatasks","casaviewer"] |
380 + | for repo in repositories: |
381 + | print("") |
382 + | print("Fetching Repository: {}".format(repo)) |
383 + | cmd = ("git clone " + repo_path + repo).split() |
384 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
385 + | run_shell_command(cmd, source_dir) |
390 386 | |
391 - | def gather_single_tests(path, workpath,test): |
387 + | if merge_target is not None: |
392 388 | |
393 - | foundTest = False |
394 - | print("Searching for Test: {}.py".format(test)) |
395 - | if sys.version_info[0] > 2: |
396 - | import pathlib |
397 - | for filename in pathlib.Path(path).rglob('{}.py'.format(test)): |
398 - | foundTest = True |
399 - | shutil.copy2(filename, workpath) |
400 - | |
401 - | if not foundTest: |
402 - | print("Could Not Find Test: {}.py".format(test)) |
389 + | cmd = ("git checkout " + merge_target).split() |
390 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
391 + | run_shell_command(cmd, source_dir + "/" + repo) |
403 392 | |
404 - | def print_test_classes(testnames): |
405 - | for test in testnames: |
406 - | pytest.main(["--collect-only", "-q", "-v", test]) |
393 + | if is_in_remote(branch,repo_path, repo): # Test if the branch is in the remote repository |
394 + | print("\tMerging {} into {}".format(branch, merge_target)) |
395 + | cmd = ("git merge " + branch).split() |
396 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
397 + | run_shell_command(cmd, source_dir + "/" + repo) |
398 + | else: |
399 + | print("\t{} not in Remote Repository {}".format(branch,repo)) |
400 + | if os.path.isfile(source_dir+"/casa6/build.conf"): |
401 + | print("\tCheckout from build.conf") |
402 + | branchtag = "tags/{}".format(read_conf(source_dir+"/casa6/build.conf")[repo]) |
403 + | print("\tTag: " + branchtag) |
404 + | cmd = ("git checkout " + branchtag).split() |
405 + | else: |
406 + | print("No casa6/build.conf found. Defaulting to master") |
407 + | cmd = ("git checkout origin/{}".format(merge_target)).split() |
408 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
409 + | run_shell_command(cmd, source_dir + "/" + repo) |
407 410 | |
408 - | def clean_working_directory(workdir): |
411 + | else: |
409 412 | |
410 - | print("Cleaning: {}".format(workdir)) |
411 - | if os.path.exists(workdir): |
412 - | shutil.rmtree(workdir) |
413 + | # Use Local build.conf to get build tags to git checkout |
414 + | if os.path.isfile(source_dir+"/casa6/build.conf"): |
415 + | branchtag = "tags/{}".format(read_conf(source_dir+"/casa6/build.conf")[repo]) |
416 + | print("\tTag: " + branchtag) |
417 + | cmd = ("git checkout " + branchtag).split() |
418 + | else: |
419 + | # Check If Feature Branch Exists |
420 + | if is_in_remote(branch,repo_path, repo): |
421 + | cmd = ("git checkout " + branch).split() |
422 + | else: |
423 + | print("\t{} not in Remote Repository {} Defaulting to master.".format(branch,repo)) |
424 + | cmd = ("git checkout origin/master").split() |
413 425 | |
414 - | def getname(testfile): |
415 - | '''Get the test name from the command-line |
416 - | Ex: from test_clean[test1], returns test_clean''' |
417 - | n0 = testfile.rfind('[') |
418 - | n1 = testfile.rfind(']') |
419 - | if n0 != -1: |
420 - | return testfile[:n0] |
426 + | print("\tRunning: ", " ".join(str(x) for x in cmd)) |
427 + | run_shell_command(cmd, source_dir + "/" + repo) |
421 428 | |
422 - | def gettests(testfile): |
423 - | '''Get the list of specific tests from the command-line |
424 - | Ex: from test_clean[test1,test3] returns [test1,test3]''' |
425 - | n0 = testfile.rfind('[') |
426 - | n1 = testfile.rfind(']') |
427 - | if n0 != -1: |
428 - | temp = testfile[n0+1:n1] |
429 - | tests = temp.split(',') |
430 - | return tests |
429 + | for x in get_repo_test_paths(repo): |
430 + | test_paths.append(source_dir + "/" + x) |
431 431 | |
432 - | def haslist(name): |
433 - | '''Check if specific list of tests have been requested''' |
434 - | n0 = name.rfind('[') |
435 - | n1 = name.rfind(']') |
436 - | if n0 == -1: |
437 - | return False |
438 - | return True |
432 + | return test_paths |
439 433 | |
440 434 | def unpack_dmg(pkg, work_dir, outputdir): |
441 435 | mountpoint = work_dir + "/mnt" |
442 436 | if not os.path.exists(mountpoint): |
443 437 | os.makedirs(mountpoint) |
444 438 | |
445 439 | print ("Unpacking dmg: " + pkg + " to " + outputdir) |
446 440 | cmd = ("hdiutil attach " + pkg + " -mountpoint " + mountpoint).split() |
447 441 | r = ShellRunner() |
448 442 | output = r.runshell(cmd, default_timeout, cwd=os.getcwd()) |
454 448 | r = ShellRunner() |
455 449 | output = r.runshell(cmd, default_timeout, cwd=os.getcwd()) |
456 450 | return installpath |
457 451 | |
458 452 | def unpack_tarball(pkg, outputdir): |
459 453 | print ("Unpacking tarball: " + pkg + " to " + outputdir) |
460 454 | cmd = ("tar -xf " + pkg + " -C " + outputdir).split() |
461 455 | print(cmd) |
462 456 | r = ShellRunner() |
463 457 | output = r.runshell(cmd, default_timeout, cwd=os.getcwd()) |
464 - | |
458 + | |
465 459 | installpath = None |
466 - | |
467 - | print("outputdir contents:" + outputdir) |
460 + | |
461 + | print("Outputdir contents:" + outputdir) |
468 462 | for root, dirs, files in os.walk(outputdir): |
469 463 | for d in dirs: |
470 464 | print(" " + d) |
471 465 | if d.startswith("casa-"): |
472 466 | installpath = d |
473 467 | print("installpath: " + installpath) |
474 468 | break |
475 469 | |
476 470 | if installpath is None: |
477 471 | raise RuntimeError("Couldn't find a directory that looks like a Casa distribution. Expected directory name to start with 'casa-'") |
482 476 | for currentpath, folders, files in os.walk(pkg_dir): |
483 477 | for file in files: |
484 478 | #print(">>>" + os.path.join(currentpath, file)) |
485 479 | if currentpath.endswith('casatestutils') and file == 'runtest.py': |
486 480 | return(os.path.join(currentpath, file)) |
487 481 | return "/dev/null/" |
488 482 | |
489 483 | def unpack_pkg(pkg, work_dir, outputdir): |
490 484 | if not os.path.exists(outputdir): |
491 485 | os.makedirs(outputdir) |
492 - | |
493 486 | if platform.system() == "Linux": |
494 487 | installpath = unpack_tarball(pkg, outputdir) |
495 488 | print ("Package root: " + installpath) |
496 489 | exec_path = installpath + "/bin" |
497 490 | elif platform.system() == "Darwin": |
498 491 | installpath = unpack_dmg(pkg,work_dir, outputdir) |
499 492 | print("Package root: " + installpath) |
500 493 | exec_path = installpath + "/Contents/MacOS" |
501 494 | else: |
502 495 | raise Exception("Unknown operating system") |
503 496 | if exec_path is None: |
504 497 | raise Exception ("Couldn't find casa executable path") |
505 498 | casatestutils_exec_path = get_casatestutils_exec_path(installpath) |
506 499 | if casatestutils_exec_path == None: |
507 500 | raise Exception("Couldn't find casatestutils") |
508 501 | return exec_path, casatestutils_exec_path |
509 - | |
510 - | def build_xml(outfile, indir): |
511 - | import pathlib |
512 - | import xml.etree.ElementTree as ET |
513 - | |
514 - | root = ET.Element("Tests") |
515 - | |
516 - | for xml_file in pathlib.Path(indir).glob('**/*.xml'): |
517 - | #print(xml_file) |
518 - | test = str(xml_file).split("/")[-2] |
519 - | #print(test) |
520 - | xmlTree = ET.parse(xml_file) |
521 - | rootElement = xmlTree.getroot() |
522 - | root.append(rootElement) |
523 - | for element in rootElement.iter(): |
524 - | if element.tag == 'testsuites': |
525 - | element.set("testsuites",test) |
526 502 | |
527 - | tree = ET.ElementTree(root) |
528 - | with open (outfile, "wb") as files : |
529 - | tree.write(files, encoding = "UTF-8", xml_declaration = True) |
503 + | def write_conftest(conf_name): |
504 + | if platform.system() == 'Darwin': |
505 + | write_conftest_osx(conf_name) |
506 + | else: |
507 + | write_conftest_linux(conf_name) |
530 508 | |
509 + | def run_cmd(cmd): |
510 + | try: |
511 + | from casampi.MPIEnvironment import MPIEnvironment |
512 + | if MPIEnvironment.is_mpi_enabled: |
513 + | pytest.main(cmd) |
514 + | else: |
515 + | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd , env={**os.environ}) |
516 + | except: |
517 + | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd, env={**os.environ}) |
518 + | |
519 + | def setup_and_run(cmd,workdir, workpath, dirname, DRY_RUN ): |
520 + | # https://docs.pytest.org/en/stable/usage.html |
521 + | cmd = ["--verbose"] + ["-ra"] + ["--tb=short"] + cmd |
522 + | |
523 + | if DRY_RUN: |
524 + | cmd = ["--collect-only"] + cmd |
525 + | |
526 + | if not os.path.isdir(workpath + '/xml/{}/'.format(dirname)): |
527 + | os.makedirs(workpath + '/xml/{}/'.format(dirname)) |
528 + | xmlfile = workpath + 'xml/{}/nose.xml'.format(dirname) |
529 + | cmd = ["--junitxml={}".format(xmlfile)] + ["-s"] + ["--disable-pytest-warnings"] + cmd |
530 + | if len(os.listdir(workpath)) < 1: # If only the XML dir was created |
531 + | print("No Tests to Run") |
532 + | sys.exit() |
533 + | else: |
534 + | myworkdir = os.getcwd() |
535 + | os.chdir(workdir + "{}/".format(dirname)) |
536 + | print("Test Directory: {}\n".format(os.getcwd())) |
537 + | print("Running Command: pytest " + " ".join(str(x) for x in cmd)) |
538 + | write_pytestini(os.path.join(os.getcwd(),"pytest.ini"),dirname) |
539 + | write_conftest(os.path.join(os.getcwd(),"conftest.py")) |
540 + | run_cmd(cmd) |
541 + | update_xml(xmlfile) |
542 + | os.remove(os.path.join(os.getcwd(),"conftest.py")) |
543 + | os.remove(os.path.join(os.getcwd(),"pytest.ini")) |
544 + | os.chdir(myworkdir) |
531 545 | ######################################################################################################################## |
532 546 | ############################################## Run ############################################### |
533 547 | ######################################################################################################################## |
534 548 | |
535 - | def run(testnames, branch=None, DRY_RUN=False): |
549 + | def run(testnames, branch=None, merge_target=None, DRY_RUN=False): |
536 550 | |
537 551 | if not HAVE_PYTEST: |
538 - | raise ImportError('No Module Named Pytest. Pytest is Required for runtest.py') |
552 + | raise ImportError('No Module Named Pytest. Pytest is Required for runtest.py') |
539 553 | |
540 554 | if HAVE_PYTEST: |
541 555 | cwd = os.getcwd() + "/" |
542 556 | workpath = os.getcwd() +"/nosedir/" |
543 557 | workdir = os.getcwd() +"/nosedir/" |
544 558 | |
545 559 | clean_working_directory(workpath) |
546 560 | # Copy Tests to Working Directory |
547 561 | os.makedirs(workdir) |
548 562 | |
557 571 | if inlist: |
558 572 | setlist.append(test) |
559 573 | inlist = False |
560 574 | testnames = setlist |
561 575 | print("Tests: {}".format(sorted(testnames))) |
562 576 | gittest = True |
563 577 | if branch ==None: |
564 578 | branch = 'master' |
565 579 | # Only Checkout When Needed |
566 580 | if any([False if ".py" in x else True for x in testnames ]): |
567 - | testpaths = fetch_tests(workdir, branch) |
581 + | testpaths = fetch_tests(workdir, branch, merge_target) |
568 582 | os.makedirs(workdir + "tests/") |
569 583 | for path in testpaths: |
570 584 | gather_all_tests(path, workdir + "tests/") |
571 - | print(workdir + "tests/") |
585 + | print("Directory Of Tests: ", workdir + "tests/") |
572 586 | |
573 587 | for testname in testnames: |
574 588 | #print(testname) |
575 589 | cmd = [] |
576 590 | |
577 591 | # Copy Test To nosedir Directory if in cwd |
578 592 | if testname.startswith("test"): |
579 593 | test = testname |
580 594 | # Check if specific tests are requested |
581 595 | if "[" and "]" in test: |
586 600 | if len(tests) == 1: |
587 601 | teststring = tests[0] |
588 602 | elif len(tests) > 1: |
589 603 | print(tests) |
590 604 | teststring = " or ".join(tests) |
591 605 | |
592 606 | cmd = ["-k {}".format(teststring)] + cmd |
593 607 | test = testname |
594 608 | |
595 609 | # Set up Test Working Directory |
596 - | if not os.path.exists(workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])): |
597 - | print("\nSetting Working Directory: {}".format(workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))) |
598 - | os.makedirs(workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])) |
599 - | cmd = [ workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]) ] + cmd |
610 + | dirname = test if not test.endswith(".py") else test[:-3] |
611 + | if not os.path.exists(workdir + "{}/".format(dirname)): |
612 + | print("\nSetting Working Directory: {}".format(workdir + "{}/".format(dirname))) |
613 + | os.makedirs(workdir + "{}/".format(dirname)) |
614 + | cmd = [ workdir + "{}/".format(dirname) ] + cmd |
600 615 | |
601 616 | if test.endswith(".py"): |
602 617 | try: |
603 - | print("Copying: {} to {}".format(test, workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))) |
604 - | shutil.copy2(test, workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])) |
618 + | #print("Copying: {} to {}".format(test, workdir + "{}/".format(dirname))) |
619 + | shutil.copy2(test, workdir + "{}/".format(dirname)) |
605 620 | except: |
606 621 | traceback.print_exc() |
607 622 | else: |
608 623 | try: |
609 - | print("Copying: {} to {}".format(workdir + "tests/",test), workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])) |
610 - | shutil.copy2("{}{}.py".format(workdir + "tests/",test), workdir + "{}/".format(test if not test.endswith(".py") else test[:-3])) |
624 + | #print("Copying: {} to {}".format(workdir + "tests/",test), workdir + "{}/".format(dirname)) |
625 + | shutil.copy2("{}{}.py".format(workdir + "tests/",test), workdir + "{}/".format(dirname)) |
611 626 | except: |
612 627 | traceback.print_exc() |
613 - | |
614 - | # https://docs.pytest.org/en/stable/usage.html |
615 - | |
616 - | cmd = ["--verbose"] + ["-ra"] + ["--tb=short"] + cmd |
617 - | if DRY_RUN: |
618 - | cmd = ["--collect-only"] + cmd |
619 - | |
620 - | if not os.path.isdir(workpath + '/xml/{}/'.format(test if not test.endswith(".py") else test[:-3])): |
621 - | os.makedirs(workpath + '/xml/{}/'.format(test if not test.endswith(".py") else test[:-3])) |
622 - | xmlfile = workpath + 'xml/{}/nose.xml'.format(test if not test.endswith(".py") else test[:-3]) |
623 - | |
624 - | cmd = ["--junitxml={}".format(xmlfile)] + ["-s"] + ["--disable-pytest-warnings"] + cmd |
625 - | #print("Running Command: pytest {}".format(cmd)) |
626 - | #print("Work Path: {}".format(workpath)) |
627 - | if len(os.listdir(workpath)) < 1: # If only the XML dir was created |
628 - | print("No Tests to Run") |
629 - | sys.exit() |
630 - | else: |
631 - | |
632 - | myworkdir = os.getcwd() |
633 - | os.chdir("{}".format(workdir + "{}/".format(test if not test.endswith(".py") else test[:-3]))) |
634 - | print("Test Directory: {}\n".format(os.getcwd())) |
635 - | print("Running Command: pytest {}\n".format(cmd)) |
636 - | conf_name = os.path.join(os.getcwd(),"conftest.py") |
637 - | write_pytestini(os.path.join(os.getcwd(),"pytest.ini"),test if not test.endswith(".py") else test[:-3]) |
638 - | if platform.system() == 'Darwin': |
639 - | write_conftest_osx(conf_name) |
640 - | else: |
641 - | write_conftest_linux(conf_name) |
642 - | try: |
643 - | from casampi.MPIEnvironment import MPIEnvironment |
644 - | if MPIEnvironment.is_mpi_enabled: |
645 - | pytest.main(cmd) |
646 - | else: |
647 - | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd , env={**os.environ}) |
648 - | except: |
649 - | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd, env={**os.environ}) |
650 - | update_xml(xmlfile) |
651 - | os.remove(conf_name) |
652 - | os.remove(os.path.join(os.getcwd(),"pytest.ini")) |
653 - | os.chdir(myworkdir) |
628 + | setup_and_run(cmd, workdir, workpath, dirname, DRY_RUN ) |
654 629 | |
655 630 | ################################################## |
656 631 | ########## Real Path ########## |
657 632 | ################################################## |
658 633 | # Copy Test To nosedir Directory assuming it's in another location |
659 634 | elif testname.startswith("/"): |
660 635 | testpath = testname.split("[")[0] |
661 636 | cmd = [] |
662 637 | dirname = testname.split("/")[-1] |
663 638 | test = dirname |
678 653 | # Set up Test Working Directory |
679 654 | if not os.path.exists(workdir + "{}/".format(dirname)): |
680 655 | print("\nSetting Working Directory: {}".format(workdir + "{}/".format(dirname))) |
681 656 | os.makedirs(workdir + "{}/".format(dirname)) |
682 657 | cmd = [ workdir + "{}/".format(dirname) ] + cmd |
683 658 | try: |
684 659 | shutil.copy2(testpath, workdir + "{}/".format(dirname)) |
685 660 | except: |
686 661 | traceback.print_exc() |
687 662 | |
688 - | cmd = ["--verbose"] + ["-ra"] + ["--tb=short"] + cmd |
689 - | |
690 - | if DRY_RUN: |
691 - | cmd = ["--collect-only"] + cmd |
692 - | |
693 - | if not os.path.isdir(workpath + '/xml/{}/'.format(dirname)): |
694 - | os.makedirs(workpath + '/xml/{}/'.format(dirname)) |
695 - | xmlfile = workpath + 'xml/{}/nose.xml'.format(dirname) |
696 - | cmd = ["--junitxml={}".format(xmlfile)] + ["-s"] + ["--disable-pytest-warnings"] + cmd |
697 - | if len(os.listdir(workpath)) < 1: # If only the XML dir was created |
698 - | print("No Tests to Run") |
699 - | sys.exit() |
700 - | else: |
701 - | myworkdir = os.getcwd() |
702 - | os.chdir(workdir + "{}/".format(dirname)) |
703 - | print("Test Directory: {}\n".format(os.getcwd())) |
704 - | print("Running Command: pytest {}\n".format(cmd)) |
705 - | conf_name = os.path.join(os.getcwd(),"conftest.py") |
706 - | write_pytestini(os.path.join(os.getcwd(),"pytest.ini"),dirname) |
707 - | if platform.system() == 'Darwin': |
708 - | write_conftest_osx(conf_name) |
709 - | else: |
710 - | write_conftest_linux(conf_name) |
711 - | try: |
712 - | from casampi.MPIEnvironment import MPIEnvironment |
713 - | if MPIEnvironment.is_mpi_enabled: |
714 - | pytest.main(cmd) |
715 - | else: |
716 - | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd , env={**os.environ}) |
717 - | except: |
718 - | subprocess.run([sys.executable,"-m","pytest"] + pytest_args + cmd , env={**os.environ}) |
719 - | update_xml(xmlfile) |
720 - | os.remove(conf_name) |
721 - | os.remove(os.path.join(os.getcwd(),"pytest.ini")) |
722 - | os.chdir(myworkdir) |
663 + | setup_and_run(cmd, workdir, workpath, dirname, DRY_RUN ) |
723 664 | #build_xml(workpath + '/xml/xUnit.xml', workpath + '/xml/') |
724 665 | os.chdir(cwd) |
725 666 | |
726 667 | ######################################################################################################################## |
727 668 | ####################################### Run Bamboo Option ######################################## |
728 669 | ######################################################################################################################## |
729 670 | |
730 - | def run_bamboo(pkg, work_dir, branch = None, test_group = None, test_list= None, test_paths = [], test_config_path=None, ncores=2, verbosity=False, pmode=None, tests_to_ignore=None): |
671 + | def run_bamboo(pkg, work_dir, branch = None, test_group = None, test_list= None, test_paths = [], test_config_path=None, ncores=2, verbosity=False, pmode=None, tests_to_ignore=None, merge_target=None): |
731 672 | |
732 673 | if test_list is not None: |
733 674 | test_list = [x.strip() for x in test_list.split(',')] |
734 675 | if args.test_group is not None: |
735 676 | test_group = [x.strip() for x in test_group.split(',')] |
736 677 | |
737 678 | # Unpack the distribution |
738 679 | print ("run_bamboo") |
739 680 | print ("Test list: " + str (test_list)) |
740 681 | print ("Test group: " + str (test_group)) |
753 694 | if sys.platform != "darwin": |
754 695 | xvfb.start_virtual_frame_buffer() |
755 696 | |
756 697 | if args.branch == None: |
757 698 | branch = "master" |
758 699 | |
759 700 | print ("run_bamboo fetch_tests branch" + branch) |
760 701 | |
761 702 | # Clone a default set of repositories to if test paths are not provided from command line |
762 703 | if len(test_paths) == 0 : |
763 - | test_paths = fetch_tests(str(work_dir), branch) |
704 + | test_paths = fetch_tests(str(work_dir), branch, merge_target) |
764 705 | |
765 706 | test_config = None |
766 707 | if test_config_path == None: |
767 708 | test_config_path = work_dir + "/casasources/casa6/casatestutils/casatestutils/component_to_test_map.json" |
768 709 | # Read the JSON configuration |
769 710 | print ("Reading config from: " + test_config_path) |
770 711 | with open(test_config_path ) as f: |
771 712 | test_config = json.load(f) |
772 713 | |
773 714 | # Get the actual tests as list |
972 913 | if sys.platform != "darwin": |
973 914 | xvfb.signal_stop_virtual_frame_buffer() |
974 915 | print("Xvfb stopped.") |
975 916 | |
976 917 | ######################################################################################################################## |
977 918 | ######################################## Main-Start-Up ########################################### |
978 919 | ######################################################################################################################## |
979 920 | |
980 921 | if __name__ == "__main__": |
981 922 | |
982 - | print("HAVE_COVTEST: {}".format(HAVE_COVTEST)) |
983 923 | print("HAVE_PYTEST: {}".format(HAVE_PYTEST)) |
984 924 | print("") |
985 925 | |
986 926 | # List of tests to run |
987 927 | testnames = [] |
988 928 | test_paths = [] |
989 929 | |
990 930 | parser = argparse.ArgumentParser(allow_abbrev=False) |
991 931 | |
992 932 | parser.add_argument("-i", "--list",action='store_true',help='print the list of tests & tags defined in component_to_test_map.json') |
993 933 | parser.add_argument("-v", "--verbose",action='store_true',help="Verbose Test Execution") |
994 934 | parser.add_argument("-x", "--dry-run",action='store_true',help="dry run Test Execution") |
995 935 | parser.add_argument("-s", "--classes",nargs='+',metavar='test',help='print the classes from a test script') # copy of Dry-Run |
996 936 | parser.add_argument("-f", "--file",nargs='?', type=argparse.FileType('r'),help='run the tests defined in an ASCII file <list>; one test per line') |
997 937 | |
998 938 | # Component Arguments |
999 939 | parser.add_argument("-e","--mapfile", nargs='?', type=argparse.FileType('r'), help='Component to test map file', required=False) |
1000 940 | parser.add_argument("-b","--branch", help='JIRA Branch for test repository checkouts', required=False) |
941 + | parser.add_argument("--merge_target", help='JIRA Branch for test repository merge', required=False) |
1001 942 | |
1002 943 | # casa-build-utils Arguments |
1003 944 | parser.add_argument('-p','--pkg', help='Tarball or dmg', required=False) |
1004 945 | parser.add_argument('-w','--work_dir', help='Working directory.', required=False) |
1005 946 | parser.add_argument('-n','--ncores', help='Number of cores for MPI tests', default=2) |
1006 947 | parser.add_argument('-t','--test_paths', help='A comma separated list of paths containing tests.', required=False) |
1007 948 | parser.add_argument('-l','--test_list', help='Filter tests by a comma separated list of tests', required=False) |
1008 949 | parser.add_argument('-c','--test_config', help='Test configuration file', required=False) |
1009 950 | parser.add_argument('-j','--test_group', help='Filter tests by a comma separated list of components', required=False) |
1010 951 | parser.add_argument('-m','--pmode', help='Parallelization mode: serial, parallel, both', required=False) |
1011 952 | parser.add_argument('--bamboo', help='Set Bamboo Flag to True',default=False,action='store_true', required=False) |
1012 953 | parser.add_argument('-r','--rcdir', help='Casa rcdir', required=False) |
1013 - | |
1014 954 | parser.add_argument('--ignore_list', help='map file of tests to ignore', required=False) |
1015 955 | |
956 + | |
1016 957 | args, unknownArgs = parser.parse_known_args() |
1017 - | |
1018 - | print(args) |
1019 958 | |
959 + | print(args) |
1020 960 | print("") |
1021 961 | |
1022 962 | tests_to_ignore = None |
1023 963 | if args.ignore_list is not None: |
1024 964 | if args.ignore_list.endswith(".json"): |
1025 965 | ignore_test_map = json.load(open(args.ignore_list)) |
1026 966 | tests_to_ignore = [x["testScript"].strip() for x in ignore_test_map["testlist"]] |
1027 967 | else: |
1028 968 | tests_to_ignore = [x.strip() for x in args.ignore_list.split(",")] |
1029 969 | |
1030 970 | print("Operating system: " + platform.system()) |
1031 971 | print("") |
1032 - | rcdir="" |
1033 972 | |
973 + | rcdir="" |
1034 974 | if args.rcdir is not None: |
1035 975 | rcdir="--rcdir=" + args.rcdir |
1036 - | print("rcdir: " + rcdir) |
976 + | print("rcdir: " + rcdir) |
1037 977 | |
1038 978 | if args.test_group is not None: |
1039 979 | components = args.test_group |
1040 980 | components = [x.strip() for x in components.split(",")] |
1041 981 | print("Testing Components" + str(components)) |
1042 982 | print("") |
1043 983 | |
1044 984 | if not args.bamboo: |
1045 985 | if args.mapfile is not None: |
1046 986 | component_to_test_map = json.load(args.mapfile) |
1071 1011 | if len(testnames)==0: |
1072 1012 | if len(no_test_components) > 0: |
1073 1013 | print("No Test Suite for Component(s): {}".format(no_test_components)) |
1074 1014 | print("Generating Suite Using Component 'default'") |
1075 1015 | component = 'default' |
1076 1016 | for myDict in component_to_test_map["testlist"]: |
1077 1017 | if component in myDict["testGroup"]: |
1078 1018 | _isComponent = True |
1079 1019 | testnames.append(myDict["testScript"]) |
1080 1020 | |
1021 + | verbose = False |
1081 1022 | if args.verbose: |
1082 1023 | verbose = True |
1024 + | |
1083 1025 | if args.list: |
1084 1026 | try: |
1085 1027 | tmp = {} |
1086 1028 | import casatestutils as _; |
1087 1029 | with open("{}/{}".format(_.__path__[0], "component_to_test_map.json")) as ctt: |
1088 1030 | component_to_test_map = json.load(ctt) |
1089 1031 | for myDict in component_to_test_map["testlist"]: |
1090 1032 | tmp[myDict["testScript"]] = myDict["testGroup"] |
1091 1033 | for key, value in tmp.items(): |
1092 1034 | print(key,value) |
1093 1035 | except: |
1094 - | list_tests() |
1036 + | list_tests(os.getcwd()) |
1095 1037 | sys.exit(1) |
1096 1038 | |
1097 1039 | ## Dry Run |
1040 + | DRY_RUN = False |
1098 1041 | if args.dry_run or (args.classes is not None): |
1099 1042 | DRY_RUN = True |
1100 1043 | |
1101 1044 | if args.file is not None: |
1102 - | #logger.info('Reading Test List from %s: ', args.file) |
1103 1045 | for line in args.file: |
1104 1046 | try: |
1105 - | #logger.debug("Adding Test %s from file %s",re.sub(r'[\n\r]+', '',line),args.file) |
1106 1047 | testnames.append(re.sub(r'[\n\r]+', '',line)) |
1107 1048 | except: |
1108 1049 | raise Exception(" The list should contain one test per line.") |
1109 1050 | |
1110 - | if args.branch is not None: |
1111 - | JIRA_BRANCH = args.branch |
1112 - | |
1113 - | |
1114 1051 | if args.test_paths is not None: |
1115 1052 | test_paths = [x.strip() for x in args.test_paths.split(',')] |
1116 1053 | |
1117 1054 | temp_storage = [] |
1118 1055 | pytest_args = [] |
1056 + | |
1119 1057 | for arg in unknownArgs: |
1120 1058 | if arg.startswith(("-", "--")): |
1121 1059 | pytest_args.append(arg) |
1122 - | #raise ValueError('unrecognized argument: %s'%(arg)) |
1123 - | #sys.exit() |
1124 1060 | else: |
1125 1061 | if '[' in arg: |
1126 1062 | tests = [x.strip() for x in arg.split("],")] |
1127 1063 | for i in range(len(tests)): |
1128 1064 | test = tests[i] |
1129 1065 | if '[' in test and not test.endswith("]"): |
1130 1066 | tests[i] = tests[i] + "]" |
1131 1067 | for i in range(len(tests)): |
1132 1068 | test = tests[i] |
1133 - | #print(tests) |
1134 1069 | if test.find(",") < test.find('['): |
1135 1070 | temp_storage = temp_storage + test.split(',',1) |
1136 1071 | else: |
1137 1072 | temp_storage.append(test) |
1138 1073 | tests = temp_storage |
1139 1074 | else: |
1140 1075 | tests = [x.strip() for x in arg.split(",")] |
1141 1076 | for test in tests: |
1142 1077 | try: |
1143 1078 | testcases = None |
1153 1088 | if ("test_" not in real_path) or ("test_" not in real_path) or ( os.path.exists(real_path) ==False): |
1154 1089 | print("{} is not a Test File".format(test)) |
1155 1090 | continue |
1156 1091 | else: |
1157 1092 | if testcases is not None: real_path = os.path.realpath(test) + "[" + testcases |
1158 1093 | testnames.append(real_path) |
1159 1094 | |
1160 1095 | # Check if test is real path are provided |
1161 1096 | elif test.endswith(".py"): |
1162 1097 | real_path = os.path.realpath(test) |
1163 - | if ("test_" not in real_path) or ("test_" not in real_path) or ( os.path.exists(real_path) ==False): |
1098 + | if ("test_" not in real_path) or ( os.path.exists(real_path) ==False): |
1164 1099 | print("{} is not a Test File".format(test)) |
1165 1100 | continue |
1166 1101 | else: |
1167 1102 | testnames.append(real_path) |
1168 1103 | |
1169 1104 | # else Assume test exists in bitbucket |
1170 1105 | else: |
1171 1106 | testnames.append(test) |
1172 1107 | except: |
1173 1108 | traceback.print_exc() |
1109 + | |
1174 1110 | print("Arguments Sent Direct To Pytest : ",pytest_args) |
1111 + | |
1175 1112 | try: |
1176 1113 | if args.bamboo: |
1177 1114 | from testrunner.shell_runner import ShellRunner |
1178 1115 | from testrunner import xvfb_helper |
1179 1116 | from testrunner.xunit import Xunit |
1180 1117 | if args.pkg: |
1181 1118 | print("Package: " + args.pkg) |
1182 1119 | print("Test configuration file: " + str(args.test_config)) |
1183 1120 | print("Number of cores: " + str(args.ncores)) |
1184 1121 | print("Workdir: " + str(args.work_dir)) |
1185 1122 | print("branch: " + str(args.branch)) |
1186 1123 | pmodes = ['serial','parallel','both'] |
1187 1124 | if args.pmode not in pmodes: |
1188 1125 | raise Exception("Invalid pmode: '{}'. Valid modes: '{}'".format(args.pmode ,str(pmodes))) |
1189 1126 | |
1190 - | |
1191 - | run_bamboo(args.pkg, args.work_dir, args.branch, args.test_group, args.test_list, test_paths, args.test_config, args.ncores, args.verbose, args.pmode, tests_to_ignore) |
1127 + | run_bamboo(args.pkg, args.work_dir, args.branch, args.test_group, args.test_list, test_paths, args.test_config, args.ncores, args.verbose, args.pmode, tests_to_ignore, args.merge_target) |
1192 1128 | |
1193 1129 | else: |
1194 1130 | #If no tests are given, no subet tag or --all option |
1195 1131 | #print("Testnames: {}".format(testnames)) |
1196 1132 | if args.test_paths is not None: |
1197 1133 | tests = [] |
1198 1134 | test_paths = [x.strip() for x in args.test_paths.split(',')] |
1199 1135 | if len(testnames) == 0: |
1200 1136 | for test_path in test_paths: |
1201 1137 | for root, dirs, files in os.walk(test_path): |
1207 1143 | #print(test_path) |
1208 1144 | for test in testnames: |
1209 1145 | if not test.endswith(".py"): |
1210 1146 | test = test + ".py" |
1211 1147 | #print(test) |
1212 1148 | for root, dirs, files in os.walk(test_path): |
1213 1149 | for file in files: |
1214 1150 | if file == test: |
1215 1151 | tests.append(os.path.realpath(os.path.join(root, file))) |
1216 1152 | testnames = tests |
1217 - | |
1218 1153 | # This section is duplicate. TO be removed with CAS-13820 |
1219 1154 | if tests_to_ignore is not None: |
1220 1155 | print("\nTests to Ignore: ",tests_to_ignore ) |
1221 1156 | indices = [] |
1222 1157 | for i, t in enumerate(testnames): |
1223 1158 | if t.split("/")[-1].replace(".py","") in tests_to_ignore: |
1224 1159 | indices.append(i) |
1225 1160 | testnames = [v for i,v in enumerate(testnames) if i not in indices] |
1226 - | |
1227 1161 | if testnames == [] or len(testnames) == 0: |
1228 1162 | print("List of tests is empty") |
1229 1163 | parser.print_help(sys.stderr) |
1230 1164 | sys.exit(1) |
1231 - | |
1232 1165 | print("Running {} Test(s)".format(len(testnames))) |
1233 - | run(testnames, args.branch, DRY_RUN) |
1166 + | run(testnames, args.branch, args.merge_target, DRY_RUN) |
1234 1167 | except: |
1235 1168 | traceback.print_exc() |
1236 - | |