Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c347b2c
created plugin changes to change test_case status if there is a crash…
Mar 18, 2019
d3a5529
removed extraneous print statements
Apr 1, 2019
77d141e
ensuring backward compatibility
Apr 2, 2019
ed893c7
Merge pull request #27 from kuamrend/analyzer_crash_failure
cneeba Apr 2, 2019
1533fdc
changes to add verbose logs to the work directory
Apr 22, 2019
3a23bce
Fix for live logging error when the test failed in setup
May 22, 2019
f7bfff3
Merge pull request #28 from kuamrend/nechandy_live_logging_fix
zoykhan May 22, 2019
28d8095
Add timeout for live logging api calls
May 24, 2019
537046f
Add timeout of 5s to get git commit id
AnandJyrm May 27, 2019
12c6416
Redo email report
AnandJyrm May 27, 2019
2097d1a
Merge pull request #29 from kuamrend/nechandy_live_logging_timeout
zoykhan May 28, 2019
9f9f43e
Merge pull request #30 from AnandJyrm/patch-3
May 28, 2019
dc71a86
Merge pull request #31 from AnandJyrm/patch-4
zoykhan May 29, 2019
146de41
Added shorthand for test-input-file and report-dir
AnandJyrm May 31, 2019
ed454e2
Get the cafykit release for email report
AnandJyrm May 31, 2019
963ec70
update css to add cafykit release if present
AnandJyrm May 31, 2019
1cf43ff
reverting some breakages from PR #31
AnandJyrm Jun 5, 2019
290959c
Merge pull request #33 from AnandJyrm/patch-1
Jun 6, 2019
f2c2e0e
Merge pull request #32 from AnandJyrm/patch-5
Jun 6, 2019
259ba0c
printing only summary logs
Jun 6, 2019
9c668a9
Fix to breakge in 19.23.12 release
AnandJyrm Jun 6, 2019
4e1d66e
Merge pull request #34 from kuamrend/collector_logs
zoykhan Jun 6, 2019
fa496ba
Merge pull request #35 from AnandJyrm/patch-2
Jun 6, 2019
0202eb9
Safe Email
kuamrend Jun 20, 2019
1b87853
Minor fix
kuamrend Jun 20, 2019
c0ae218
Merge pull request #37 from kuamrend/safe-email
Jun 20, 2019
c8ca587
added timeout to all debug calls
Jul 17, 2019
6251016
Merge pull request #38 from kuamrend/debug_timeout
zoykhan Jul 18, 2019
6958e3a
Create cafyrun alias to run pytest scripts JIRA issue CAFY-260
shreyash45 Jul 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions bin/cafyrun
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
import pytest
import _pytest.main
import sys

# Customize messages for pytest exit codes
msg = {_pytest.main.EXIT_OK: 'OK',
_pytest.main.EXIT_TESTSFAILED: 'Tests failed',
_pytest.main.EXIT_INTERRUPTED: 'Interrupted',
_pytest.main.EXIT_INTERNALERROR: 'Internal error',
_pytest.main.EXIT_USAGEERROR: 'Usage error',
_pytest.main.EXIT_NOTESTSCOLLECTED: 'No tests collected'}

exitcode = pytest.main(sys.argv[1:])




print(msg[exitcode])
sys.exit(exitcode)

113 changes: 81 additions & 32 deletions pytest_cafy/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
import pytest

from _pytest.terminal import TerminalReporter
from _pytest.runner import runtestprotocol
from _pytest.runner import runtestprotocol, TestReport
from _pytest.mark import MarkInfo

from enum import Enum
from tabulate import tabulate
from pprint import pprint, pformat
from shutil import copyfile
from configparser import ConfigParser
from datetime import datetime
Expand Down Expand Up @@ -122,7 +123,7 @@ def pytest_addoption(parser):
group.addoption('--work-dir', dest="workdir", metavar="DIR", default=None,
help="Path for work dir")

group.addoption('--report-dir', dest="reportdir",
group.addoption('-R','--report-dir', dest="reportdir",
metavar="DIR",
default=None,
help="Path for report dir")
Expand All @@ -133,7 +134,7 @@ def pytest_addoption(parser):
type=lambda x: is_valid_param(x, file_type='topology_file'),
help='Filename of your testbed')

group.addoption('--test-input-file', action='store', dest='test_input_file',
group.addoption('-I', '--test-input-file', action='store', dest='test_input_file',
metavar='test_input_file',
type=lambda x: is_valid_param(x, file_type='input_file'),
help='Filename of your test input file')
Expand Down Expand Up @@ -534,7 +535,7 @@ def pytest_collection_modifyitems(session, config, items):
log.info("url: {}".format(url))
log.info("Calling API service for live logging of reg_id ")
params = {"reg_id": CafyLog.registration_id}
response = requests.patch(url, json=params, headers=headers)
response = requests.patch(url, json=params, headers=headers, timeout=120)
if response.status_code == 200:
log.info("Calling API service for live logging of reg_id successful")
else:
Expand All @@ -558,7 +559,7 @@ def pytest_collection_modifyitems(session, config, items):
url = '{0}/api/runs/{1}/cases'.format(os.environ.get('CAFY_API_HOST'), os.environ.get('CAFY_RUN_ID'))
log.info("url: {}".format(url))
log.info("Calling API service for live logging of collected testcases ")
response = requests.post(url, json=CafyLog.collected_testcases, headers=headers)
response = requests.post(url, json=CafyLog.collected_testcases, headers=headers, timeout=120)
if response.status_code == 200:
log.info("Calling API service for live logging of collected testcases successful")
else:
Expand Down Expand Up @@ -789,7 +790,7 @@ def initiate_analyzer(self, reg_id, test_case, debug_server):
try:
url = "http://{0}:5001/initiate_analyzer/".format(CafyLog.debug_server)
self.log.info("Calling registration service (url:%s) to initialize analyzer" % url)
response = requests.post(url, data=params)
response = requests.post(url, data=params, timeout=300)
if response.status_code == 200:
self.log.info("Analyzer initialized")
return True
Expand All @@ -813,7 +814,7 @@ def pytest_runtest_teardown(self, item, nextitem):
self.log.set_testcase("Teardown")
else:
testcase_name = self.get_test_name(nextitem.nodeid)
self.log.set_testcase(testcase_name)
# self.log.set_testcase(testcase_name)
testcase_name = self.get_test_name(item.nodeid)
self.log.info('Teardown module for testcase {}'.format(testcase_name))

Expand Down Expand Up @@ -863,7 +864,7 @@ def check_analyzer_status(self, params, headers):
try:
url = "http://{0}:5001/end_test_case/".format(CafyLog.debug_server)
self.log.info("Calling registration service (url:%s) to check analyzer status" % url)
response = requests.get(url, data=params)
response = requests.get(url, data=params, timeout=60)
if response.status_code == 200:
return response.json()['analyzer_status']
else:
Expand Down Expand Up @@ -894,7 +895,7 @@ def pytest_runtest_logreport(self, report):
try:
url = 'http://{0}:5001/registertest/'.format(CafyLog.debug_server)
self.log.info("Calling registration service to start handshake(url:%s" % url)
response = requests.post(url, json=params, headers=headers)
response = requests.post(url, json=params, headers=headers, timeout=300)
if response.status_code == 200:
self.log.info("Handshake part of registration service was successful")
else:
Expand All @@ -905,14 +906,6 @@ def pytest_runtest_logreport(self, report):


if report.when == 'teardown':
if self.reg_dict:
reg_id = self.reg_dict.get('reg_id')
test_class = report.nodeid.split('::')[1]
if (test_class not in self.analyzer_testcase.keys()) or self.analyzer_testcase.get(test_class) == 1:
analyzer_status = self.post_testcase_status(reg_id, testcase_name, CafyLog.debug_server)
self.log.info('Analyzer Status is {}'.format(analyzer_status))
else:
self.log.info('Analyzer is not invoked as testcase failed in setup')
status = "unknown"
if testcase_name in self.testcase_dict:
status = self.testcase_dict[testcase_name]
Expand Down Expand Up @@ -1034,6 +1027,47 @@ def pytest_runtest_logreport(self, report):
else:
self.testcase_failtrace_dict[testcase_name] = None

# Add the testcase status to testcase_dict as error if the test failed in setup
try:
if report.when == 'setup' and report.outcome == 'failed':
testcase_name = self.get_test_name(report.nodeid)
self.testcase_dict[testcase_name] = 'error'
except Exception as e:
self.log.error("Error getting the testcase status for setup failure: {}".format(e))


@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_runtest_makereport(self, item, call):
outcome = (yield)
if call.when =='call':
report = outcome.get_result()
testcase_name = self.get_test_name(report.nodeid)
if self.reg_dict:
reg_id = self.reg_dict.get('reg_id')
test_class = report.nodeid.split('::')[1]
if (test_class not in self.analyzer_testcase.keys()) or self.analyzer_testcase.get(test_class) == 1:
analyzer_status = self.post_testcase_status(reg_id, testcase_name, CafyLog.debug_server)
self.log.info('Analyzer Status is {}'.format(analyzer_status))
else:
self.log.info('Analyzer is not invoked as testcase failed in setup')
if isinstance(analyzer_status, bool):
return
failures = json.loads(analyzer_status.get('failures',[]))
if len(failures):
self.log.error('Test case failed due to crash/traceback {}'.format(pformat(failures)))
test_outcome = 'failed'
report = TestReport(
report.nodeid,
report.location,
report.keywords,
test_outcome,
report.longrepr,
report.when,
report.sections,
report.duration,
)
outcome.force_result(report)


def check_call_report(self, item, nextitem):
"""
Expand Down Expand Up @@ -1284,7 +1318,7 @@ def invoke_reg_on_failed_testcase(self, params, headers):
try:
url = "http://{0}:5001/startdebug/".format(CafyLog.debug_server)
self.log.info("Calling registration service (url:%s) to start collecting" % url)
response = requests.post(url, json=params, headers=headers)
response = requests.post(url, json=params, headers=headers, timeout=1500)
if response.status_code == 200:
return response
else:
Expand All @@ -1301,7 +1335,7 @@ def invoke_rc_on_failed_testcase(self, params, headers):
try:
url = "http://{0}:5003/startrootcause/".format(CafyLog.debug_server)
self.log.info("Calling RC engine to start rootcause (url:%s)" % url)
response = requests.post(url, json=params, headers=headers)
response = requests.post(url, json=params, headers=headers, timeout=300)
if response.status_code == 200:
return response
else:
Expand Down Expand Up @@ -1330,13 +1364,17 @@ def pytest_terminal_summary(self, terminalreporter):
if junitxml_file_path != _junitxml_filename:
copyfile(_junitxml_filename, junitxml_file_path)
os.chmod(junitxml_file_path, 0o775)

temp_list = []
terminalreporter.write_line("\n TestCase Summary Status Table")
for k,v in self.testcase_dict.items():
temp_list.append((k,v))
print (tabulate(temp_list, headers=['Testcase_name', 'Status'], tablefmt='grid'))
if not self.no_email:
self._sendemail()
terminalreporter.write_line("\n TestCase Summary Status Table")
temp_list = []
for k,v in self.testcase_dict.items():
temp_list.append((k,v))
print (tabulate(temp_list, headers=['Testcase_name', 'Status'], tablefmt='grid'))
try:
self._sendemail()
except Exception as err:
self.log.error("Error when sending email: {err}".format(err=str(err)))


#Unset environ variables cafykit_mongo_learn & cafykit_mongo_read if set
Expand Down Expand Up @@ -1403,7 +1441,7 @@ def _get_analyzer_log(self):
"debug_server_name": CafyLog.debug_server}
url = 'http://{0}:5001/get_analyzer_log/'.format(CafyLog.debug_server)
try:
response = requests.get(url, data=params)
response = requests.get(url, data=params, timeout=300)
if response is not None and response.status_code == 200:
if response.text:
if 'Content-Disposition' in response.headers:
Expand Down Expand Up @@ -1435,15 +1473,22 @@ def pytest_sessionfinish(self):
url = 'http://{0}:5001/uploadcollectorlogfile/'.format(CafyLog.debug_server)
print("url = ", url)
self.log.info("Calling registration upload collector logfile service (url:%s)" %url)
response = requests.post(url, json=params, headers=headers)
response = requests.post(url, json=params, headers=headers, timeout=300)
if response is not None and response.status_code == 200:
if response.text:
self.log.info ("Debug Collector logs: %s" %(response.text))
summary_log = response.text
if '+'*120 in response.text:
summary_log, verbose_log = response.text.split('+'*120)
self.log.info ("Debug Collector logs: %s" %(summary_log))
if 'Content-Disposition' in response.headers:
debug_collector_log_filename = response.headers['Content-Disposition'].split('filename=')[-1]
collector_log_file_full_path = os.path.join(CafyLog.work_dir,debug_collector_log_filename)
with open(collector_log_file_full_path, 'w') as f:
f.write(response.text)
f.write(summary_log)
verbose_log_file_path = collector_log_file_full_path.replace("debug_collection.log",
"verbose_collection.log")
with open(verbose_log_file_path, 'w') as f:
f.write(verbose_log)
try:
DebugLibrary.convert_collector_logs_to_json(collector_log_file_full_path)
except:
Expand All @@ -1453,7 +1498,7 @@ def pytest_sessionfinish(self):

url = 'http://{0}:5001/deleteuploadedfiles/'.format(CafyLog.debug_server)
self.log.info("Calling registration delete upload file service (url:%s)" % url)
response = requests.post(url, json=params, headers=headers)
response = requests.post(url, json=params, headers=headers, timeout=300)
if response.status_code == 200:
self.log.info("Topology and input files deleted from registration server")
else:
Expand Down Expand Up @@ -1537,15 +1582,19 @@ def __init__(self, terminalreporter, testcase_dict, testcase_failtrace_dict, arc
# Run Info
self.exec_host = platform.node()
self.python_version = platform.python_version()
self. platform = platform.platform()
self.platform = platform.platform()
try:
self.cafykit_release = os.path.basename(os.environ.get("VIRTUAL_ENV"))
except:
self.cafykit_release = None
self.testbed = None
self.registration_id = CafyLog.registration_id
self.submitter = EmailReport.USER
self.cafy_repo = EmailReport.CAFY_REPO
self.topo_file = topo_file
self.run_dir = self.terminalreporter.startdir.strpath
try:
self.git_commit_id = subprocess.check_output(['git', 'rev-parse', 'origin/master']).decode("utf-8").replace('\n', '')
self.git_commit_id = subprocess.check_output(['git', 'rev-parse', 'origin/master'], timeout=5).decode("utf-8").replace('\n', '')
except Exception:
self.git_commit_id = None
self.archive = CafyLog.work_dir
Expand Down
Loading