#! /usr/bin/env python # execute(), fetch(), notify() are based on https://github.com/getlantern/build-automation/blob/master/build.py import argparse import os import string import time import traceback from subprocess import Popen, PIPE default_repo_url = 'https://github.com/Cyan4973/zstd.git' test_dir_name = 'speedTest' email_header = '[ZSTD_speedTest]' def log(text): print time.strftime("%Y/%m/%d %H:%M:%S") + ' - ' + text def execute(command, print_output=False, print_error=True): log("> " + command) popen = Popen(command, stdout=PIPE, stderr=PIPE, shell=True, cwd=execute.cwd) itout = iter(popen.stdout.readline, b"") iterr = iter(popen.stderr.readline, b"") stdout_lines = list(itout) if print_output: print ''.join(stdout_lines) stderr_lines = list(iterr) if print_output: print ''.join(stderr_lines) popen.communicate() if popen.returncode is not None and popen.returncode != 0: if not print_output and print_error: print ''.join(stderr_lines) raise RuntimeError(''.join(stderr_lines)) return stdout_lines + stderr_lines execute.cwd = None def does_command_exist(command): try: execute(command, False, False); except Exception as e: return False return True def fetch(): execute('git fetch -p') output = execute('git branch -rl') for line in output: if "HEAD" in line: output.remove(line) # remove "origin/HEAD -> origin/dev" branches = map(lambda l: l.strip(), output) return map(lambda b: (b, execute('git show -s --format=%h ' + b)[0].strip()), branches) def notify(branch, commit, last_commit): text_tmpl = string.Template('Changes since $last_commit:\r\n$commits') branch = branch.split('/')[1] fmt = '--format="%h: (%an) %s, %ar"' if last_commit is None: commits = execute('git log -n 10 %s %s' % (fmt, commit)) else: commits = execute('git --no-pager log %s %s..%s' % (fmt, last_commit, commit)) text = text_tmpl.substitute({'last_commit': last_commit, 'commits': ''.join(commits)}) print str("commits for %s: %s" % (commit, text)) def compile(branch, commit, dry_run): local_branch = string.split(branch, '/')[1] version = local_branch.rpartition('-')[2] version = version + '_' + commit execute('git checkout -- . && git checkout ' + branch) if not dry_run: execute('VERSION=' + version + '; make clean zstdprogram') def get_last_commit(resultsFileName): if not os.path.isfile(resultsFileName): return None, None, None commit = None cspeed = [] dspeed = [] with open(resultsFileName,'r') as f: for line in f: words = line.split() if len(words) == 2: # branch + commit commit = words[1]; cspeed = [] dspeed = [] if (len(words) == 8): cspeed.append(float(words[3])) dspeed.append(float(words[5])) #if commit != None: # print "commit=%s cspeed=%s dspeed=%s" % (commit, cspeed, dspeed) return commit, cspeed, dspeed def benchmark_and_compare(branch, commit, resultsFileName, lastCLevel, testFilePath, fileName, last_cspeed, last_dspeed, lower_limit, maxLoadAvg, message): sleepTime = 30 while os.getloadavg()[0] > maxLoadAvg: log("WARNING: bench loadavg=%.2f is higher than %s, sleeping for %s seconds" % (os.getloadavg()[0], maxLoadAvg, sleepTime)) time.sleep(sleepTime) start_load = str(os.getloadavg()) result = execute('programs/zstd -qi5b1e' + str(lastCLevel) + ' ' + testFilePath) end_load = str(os.getloadavg()) linesExpected = lastCLevel + 2; if len(result) != linesExpected: log("ERROR: number of result lines=%d is different that expected %d" % (len(result), linesExpected)) return "" with open(resultsFileName, "a") as myfile: myfile.write(branch + " " + commit + "\n") myfile.writelines(result) myfile.close() if (last_cspeed == None): return "" commit, cspeed, dspeed = get_last_commit(resultsFileName) text = "" for i in range(0, min(len(cspeed), len(last_cspeed))): if (cspeed[i]/last_cspeed[i] < lower_limit): text += "WARNING: File=%s level=%d cspeed=%s last=%s diff=%s\n" % (fileName, i+1, cspeed[i], last_cspeed[i], cspeed[i]/last_cspeed[i]) if (dspeed[i]/last_dspeed[i] < lower_limit): text += "WARNING: File=%s level=%d dspeed=%s last=%s diff=%s\n" % (fileName, i+1, dspeed[i], last_dspeed[i], dspeed[i]/last_dspeed[i]) if text: text = message + ("\nmaxLoadAvg=%s load average at start=%s end=%s\n" % (maxLoadAvg, start_load, end_load)) + text return text def send_simple_email(emails, email_topic, have_mutt, have_mail): if have_mutt: execute('mutt -s "' + email_header + ' ' + email_topic + '" ' + emails + '