diff --git a/tools/donate-cpu-server.py b/tools/donate-cpu-server.py
index fca62838a..ac4bca607 100755
--- a/tools/donate-cpu-server.py
+++ b/tools/donate-cpu-server.py
@@ -22,7 +22,7 @@ import operator
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
# changes)
-SERVER_VERSION = "1.3.1"
+SERVER_VERSION = "1.3.2"
OLD_VERSION = '1.90'
@@ -67,6 +67,7 @@ def overviewReport() -> str:
html = '
daca@home\n'
html += 'daca@home
\n'
html += 'Crash report
\n'
+ html += 'Timeout report
\n'
html += 'Stale report
\n'
html += 'Diff report
\n'
html += 'HEAD report
\n'
@@ -82,7 +83,7 @@ def overviewReport() -> str:
def fmt(a: str, b: str, c: str = None, d: str = None, e: str = None, link: bool = True) -> str:
- column_width = [40, 10, 5, 6, 6, 8]
+ column_width = [40, 10, 5, 7, 7, 8]
ret = a
while len(ret) < column_width[0]:
ret += ' '
@@ -218,6 +219,47 @@ def crashReport(results_path: str) -> str:
return html
+def timeoutReport(results_path: str) -> str:
+ html = 'Timeout report\n'
+ html += 'Timeout report
\n'
+ html += '\n'
+ html += '' + fmt('Package', 'Date Time', OLD_VERSION, 'Head', link=False) + '\n'
+ current_year = datetime.date.today().year
+ for filename in sorted(glob.glob(os.path.expanduser(results_path + '/*'))):
+ if not os.path.isfile(filename):
+ continue
+ datestr = ''
+ with open(filename, 'rt') as file_:
+ for line in file_:
+ line = line.strip()
+ if line.startswith('cppcheck: '):
+ if OLD_VERSION not in line:
+ # Package results seem to be too old, skip
+ break
+ else:
+ # Current package, parse on
+ continue
+ if line.startswith(str(current_year) + '-') or line.startswith(str(current_year - 1) + '-'):
+ datestr = line
+ if line.startswith('count:'):
+ if line.find('TO!') < 0:
+ break
+ package = filename[filename.rfind('/')+1:]
+ counts = line.strip().split(' ')
+ c2 = ''
+ if counts[2] == 'TO!':
+ c2 = 'Timeout'
+ c1 = ''
+ if counts[1] == 'TO!':
+ c1 = 'Timeout'
+ html += fmt(package, datestr, c2, c1) + '\n'
+ break
+
+ html += '
\n'
+ html += '\n'
+ return html
+
+
def staleReport(results_path: str) -> str:
html = 'Stale report\n'
html += 'Stale report
\n'
@@ -773,6 +815,9 @@ class HttpClientThread(Thread):
elif url == 'crash.html':
html = crashReport(self.resultPath)
httpGetResponse(self.connection, html, 'text/html')
+ elif url == 'timeout.html':
+ html = timeoutReport(self.resultPath)
+ httpGetResponse(self.connection, html, 'text/html')
elif url == 'stale.html':
html = staleReport(self.resultPath)
httpGetResponse(self.connection, html, 'text/html')
diff --git a/tools/donate-cpu.py b/tools/donate-cpu.py
index 6e0cf68df..498060a2e 100755
--- a/tools/donate-cpu.py
+++ b/tools/donate-cpu.py
@@ -172,6 +172,7 @@ while True:
print("No files to process")
continue
crash = False
+ timeout = False
count = ''
elapsed_time = ''
results_to_diff = []
@@ -193,6 +194,10 @@ while True:
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
# No sourcefile found (for example only headers present)
count += ' 0'
+ elif c == RETURN_CODE_TIMEOUT:
+ # Timeout
+ count += ' TO!'
+ timeout = True
else:
crash = True
count += ' Crash!'
@@ -220,7 +225,7 @@ while True:
info_output += 'info messages:\n' + head_info_msg
if 'head' in cppcheck_versions:
output += 'head results:\n' + results_to_diff[cppcheck_versions.index('head')]
- if not crash:
+ if not crash and not timeout:
output += 'diff:\n' + diff_results(work_path, cppcheck_versions[0], results_to_diff[0], cppcheck_versions[1], results_to_diff[1]) + '\n'
if package_url:
print('=========================================================')
diff --git a/tools/donate_cpu_lib.py b/tools/donate_cpu_lib.py
index a24f4073d..e14131392 100644
--- a/tools/donate_cpu_lib.py
+++ b/tools/donate_cpu_lib.py
@@ -13,7 +13,13 @@ import tarfile
# Version scheme (MAJOR.MINOR.PATCH) should orientate on "Semantic Versioning" https://semver.org/
# Every change in this script should result in increasing the version number accordingly (exceptions may be cosmetic
# changes)
-CLIENT_VERSION = "1.1.42"
+CLIENT_VERSION = "1.2.0"
+
+# Timeout for analysis with Cppcheck in seconds
+CPPCHECK_TIMEOUT = 60 * 60
+
+# Return code that is used to mark a timed out analysis
+RETURN_CODE_TIMEOUT = -999
def check_requirements():
@@ -249,12 +255,18 @@ def run_command(cmd):
print(cmd)
startTime = time.time()
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- comm = p.communicate()
+ try:
+ comm = p.communicate(timeout=CPPCHECK_TIMEOUT)
+ return_code = p.returncode
+ except subprocess.TimeoutExpired:
+ p.kill()
+ comm = p.communicate()
+ return_code = RETURN_CODE_TIMEOUT
stop_time = time.time()
stdout = comm[0].decode(encoding='utf-8', errors='ignore')
stderr = comm[1].decode(encoding='utf-8', errors='ignore')
elapsed_time = stop_time - startTime
- return p.returncode, stdout, stderr, elapsed_time
+ return return_code, stdout, stderr, elapsed_time
def scan_package(work_path, cppcheck_path, jobs, libraries):
@@ -300,6 +312,9 @@ def scan_package(work_path, cppcheck_path, jobs, libraries):
else:
stacktrace = stdout[last_check_pos:]
return returncode, stacktrace, '', returncode, options, ''
+ if returncode == RETURN_CODE_TIMEOUT:
+ print('Timeout!')
+ return returncode, stdout, '', elapsed_time, options, ''
if returncode != 0:
print('Error!')
if returncode > 0:
diff --git a/tools/test-my-pr.py b/tools/test-my-pr.py
index 3c762c315..98f4cd9d0 100755
--- a/tools/test-my-pr.py
+++ b/tools/test-my-pr.py
@@ -69,6 +69,7 @@ if __name__ == "__main__":
packages_processed = 0
crashes = []
+ timeouts = []
while packages_processed < args.p and len(packages_idxs) > 0:
package = lib.get_package(lib.server_address, packages_idxs.pop())
@@ -90,12 +91,18 @@ if __name__ == "__main__":
master_crashed = False
your_crashed = False
+ master_timeout = False
+ your_timeout = False
+
libraries = lib.get_libraries()
c, errout, info, time, cppcheck_options, timing_info = lib.scan_package(work_path, master_dir, jobs, libraries)
if c < 0:
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
# No sourcefile found (for example only headers present)
print('Error: 101')
+ elif c == lib.RETURN_CODE_TIMEOUT:
+ print('Master timed out!')
+ master_timeout = True
else:
print('Master crashed!')
master_crashed = True
@@ -106,6 +113,9 @@ if __name__ == "__main__":
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
# No sourcefile found (for example only headers present)
print('Error: 101')
+ elif c == lib.RETURN_CODE_TIMEOUT:
+ print('Your code timed out!')
+ your_timeout = True
else:
print('Your code crashed!')
your_crashed = True
@@ -121,6 +131,16 @@ if __name__ == "__main__":
who = 'Your'
crashes.append(package + ' ' + who)
+ if master_timeout or your_timeout:
+ who = None
+ if master_timeout and your_timeout:
+ who = 'Both'
+ elif master_timeout:
+ who = 'Master'
+ else:
+ who = 'Your'
+ timeouts.append(package + ' ' + who)
+
with open(result_file, 'a') as myfile:
myfile.write(package + '\n')
diff = lib.diff_results(work_path, 'master', results_to_diff[0], 'your', results_to_diff[1])
@@ -134,4 +154,8 @@ if __name__ == "__main__":
myfile.write('\n\ncrashes\n')
myfile.write('\n'.join(crashes))
+ with open(result_file, 'a') as myfile:
+ myfile.write('\n\ntimeouts\n')
+ myfile.write('\n'.join(timeouts))
+
print('Result saved to: ' + result_file)