[pypy-commit] lang-smalltalk default: FRAMEWORK ALL THE THINGS (related to codespeed and benchmarks)

timfel noreply at buildbot.pypy.org
Tue Apr 30 15:43:35 CEST 2013


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: 
Changeset: r356:37a1dfe0e066
Date: 2013-04-30 15:42 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/37a1dfe0e066/

Log:	FRAMEWORK ALL THE THINGS (related to codespeed and benchmarks)

diff --git a/benchmarks.py b/benchmarks.py
--- a/benchmarks.py
+++ b/benchmarks.py
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 import os
+import shutil
 import socket
 import subprocess
 import sys
@@ -12,159 +13,201 @@
 # You need to enter the real URL and have the server running
 CODESPEED_URL = 'http://speed.bithug.org/'
 
-# Executables (assumed to be in the local directory)
-executables = ["targetimageloadingsmalltalk-c", "coglinux/squeak"]
 
-# Arguments (inserted between executable and benchmark)
-executable_arguments = [
-    ["images/%s.image" % SqueakImage, '-m', 'runSPyBenchmarks'],
-    ['-vm-display-X11', '-headless', "images/%s.image" % SqueakImage, '../benchmarks.st']]
+class Project(object):
+    def __init__(self, name, executables={}, arguments="", commitid=None):
+        self.commitid = commitid if commitid else self.get_commitid()
+        self.name = name
+        self.executables = executables
+        self.arguments = arguments
 
-def build_data(executable, benchmark, result):
-    # Mandatory fields
-    return {
-        'commitid': COMMIT_ID,
-        'branch': 'default',
-        'project': 'lang-smalltalk',
-        'executable': executable,
-        'benchmark': benchmark,
-        'environment': socket.gethostname(),
-        'result_value': str(result),
-    }
-    # Optional fields
-    # {
-    #     'std_dev': 1.11111, # Optional. Default is blank
-    #     'max': 4001.6, # Optional. Default is blank
-    #     'min': 3995.1, # Optional. Default is blank
-    # }
+    def run(self):
+        for executable in self.executables:
+            yield executable.name, executable.run(self.arguments)
 
+    def post_results(self):
+        for executable, output in self.run():
+            benchmarks = output.split('\n')
+            for s in benchmarks:
+                if ';' in s:
+                    name, time = s.split(';')
+                    self.add(executable, name, time)
 
-def ungzip(url, name, target):
-    import gzip
-    zip_contents = urllib2.urlopen(url).read()
-    with open(name, "w") as f:
-        f.write(zip_contents)
-    f = gzip.open(name)
-    with open(target, "w") as s:
-        s.write(f.read())
+    def add(self, executable, benchmark, result):
+        print "Saving result %s for executable %s, benchmark %s" % (
+            result, executable, benchmark)
+        data = self.build_data(executable, benchmark, result)
+        params = urllib.urlencode(data)
+        response = "None"
+        print "Saving result for executable %s, revision %s, benchmark %s" % (
+            data['executable'], data['commitid'], data['benchmark'])
+        try:
+            f = urllib2.urlopen(CODESPEED_URL + 'result/add/', params)
+        except urllib2.HTTPError as e:
+            print str(e)
+            print e.read()
+            return
+        response = f.read()
+        f.close()
+        print "Server (%s) response: %s\n" % (CODESPEED_URL, response)
 
-def untar(name, target):
-    import tarfile
-    try:
-        f = tarfile.open(name)
-        f.extractall(target)
-    finally:
-        f.close()
-
-def download_prerequesites():
-    clean_workspace()
-    print 'Downloading',
-    download_cog()
-    print 'done'
-
-def download_cog():
-    if sys.platform == "win32":
-        url = "http://www.mirandabanda.org/files/Cog/VM/VM.r2714/cogwin-13.13.2714.zip"
-        unzip(url, 'cogwin.zip', '.')
-    else:
-        url = "http://www.mirandabanda.org/files/Cog/VM/VM.r2714/coglinux-13.13.2714.tgz"
-        print '.',
-        ungzip(url, 'coglinux.tgz', 'coglinux.tar')
-        print '.',
-        untar('coglinux.tar', '.')
-
-def clean_workspace():
-    print 'Cleaning workspace',
-    for f in ["image.tgz", "image.tar",
-              'coglinux.tgz', 'coglinux.tar',
-              'cogwin.zip']:
+    def get_commitid(self):
         try:
-            os.remove(f)
+            pipe = subprocess.Popen(
+                ["hg", "log", "-l", "1", "--template", "{rev}:{node}"],
+                stdout=subprocess.PIPE
+            )
+            if pipe.wait() == 0:
+                return pipe.stdout.read()
         except:
             pass
-        print '.',
-    for d in ['coglinux', 'cogwin']:
         try:
-            shutil.rmtree(d)
+            pipe = subprocess.Popen(
+                ["git", "log", "-1", "--pretty=%H"],
+                stdout=subprocess.PIPE
+            )
+            if pipe.wait() == 0:
+                return pipe.stdout.read()
         except:
             pass
-        print '.',
-    print 'done'
+        raise Exception("commitid not found. not a git or hg repo")
 
-def get_commitid():
-    try:
-        pipe = subprocess.Popen(
-            ["hg", "log", "-l", "1", "--template", "{branch}-{rev}"],
-            stdout=subprocess.PIPE
-        )
-        if pipe.wait() == 0:
-            return pipe.stdout.read()
-    except:
-        pass
-    try:
-        pipe = subprocess.Popen(
-            ["git", "log", "-1", "--pretty=%H"],
-            stdout=subprocess.PIPE
-        )
-        if pipe.wait() == 0:
-            return pipe.stdout.read()
-    except:
-        pass
-    raise Exception("commitid not found. not a git or hg repo")
+    def build_data(self, executable, benchmark, result):
+        # Mandatory fields
+        return {
+            'commitid': self.commitid,
+            'branch': 'default',
+            'project': self.name,
+            'executable': executable,
+            'benchmark': benchmark,
+            'environment': socket.gethostname(),
+            'result_value': str(result),
+        }
+        # Optional fields
+        # {
+        #     'std_dev': 1.11111, # Optional. Default is blank
+        #     'max': 4001.6, # Optional. Default is blank
+        #     'min': 3995.1, # Optional. Default is blank
+        # }
 
-COMMIT_ID = None
 
+class Archive(object):
+    def __init__(self, filename, target, func):
+        self.filename = filename
+        self.func = func
+        self.target = target
 
-def add(executable, benchmark, result):
-    print "Saving result %s for executable %s, benchmark %s" % (
-        result, executable, benchmark)
-    global COMMIT_ID
-    if COMMIT_ID is None:
-        COMMIT_ID = get_commitid()
-    data = build_data(executable, benchmark, result)
-    params = urllib.urlencode(data)
-    response = "None"
-    print "Saving result for executable %s, revision %s, benchmark %s" % (
-        data['executable'], data['commitid'], data['benchmark'])
-    try:
-        f = urllib2.urlopen(CODESPEED_URL + 'result/add/', params)
-    except urllib2.HTTPError as e:
-        print str(e)
-        print e.read()
-        return
-    response = f.read()
-    f.close()
-    print "Server (%s) response: %s\n" % (CODESPEED_URL, response)
+    def extract(self):
+        self.func(self.filename, self.target)
 
-def update_image(suffix):
-    with open('update.st', 'w') as f:
-        f.write('''Smalltalk snapshot: true andQuit: true.''')
-    pipe = subprocess.Popen(
-        ['coglinux/squeak%s -vm-display-X11 -headless images/%s ../update.st' % (suffix, SqueakImage)],
-        shell=True)
-    pipe.wait()
-    os.remove('update.st')
+    def __enter__(self):
+        self.extract()
 
+    def __exit__(self, *_):
+        if os.path.exists(self.target) and os.path.isfile(self.target):
+            os.remove(self.target)
 
-def run():
-    suffix = ".exe" if sys.platform == "win32" else ""
-    update_image(suffix)
 
-    for i, executable in enumerate(executables):
+class Executable(object):
+    def __init__(self, name, path, url=None, callback=None):
+        self.name = name
+        self.path = path
+        if url:
+            self.download(url, callback=callback)
+
+    def ungzip(self, source, target):
+        import gzip
+        contents = gzip.open(source).read()
+        with open(target, "w") as t:
+            t.write(contents)
+
+    def untar(self, source, target):
+        import tarfile
+        try:
+            f = tarfile.open(source)
+            f.extractall(target)
+        finally:
+            f.close()
+
+    def download(self, url, callback=None):
+        if os.path.exists(self.path):
+            shutil.rmtree(os.path.dirname(self.path))
+        filename = url.rsplit("/", 1)[1]
+        if os.path.exists(filename):
+            os.remove(filename)
+        print "Downloading from", url
+        with open(filename, "w") as f:
+            f.write(urllib2.urlopen(url).read())
+        try:
+            print "Extracting", filename
+            if filename.endswith(".tar.gz") or filename.endswith(".tgz"):
+                tarfile = os.path.basename(filename) + ".tar"
+                with Archive(filename, tarfile, self.ungzip):
+                    Archive(tarfile, ".", self.untar).extract()
+            elif filename.endswith(".tar"):
+                Archive(filename, ".", self.untar).extract()
+            else:
+                raise NotImplementedError
+        finally:
+            os.remove(filename)
+        if callback:
+            callback(self)
+
+    def run(self, args):
         print 'Calling %s ...' % executable
         pipe = subprocess.Popen(
-            ["./%s%s" % (executable, suffix)] + executable_arguments[i],
+            ["%s" % executable.path] + args,
             stdout=subprocess.PIPE
         )
         out, err = pipe.communicate()
         errcode = pipe.wait()
         print out
-        benchmarks = out.split('\n')
-        for s in benchmarks:
-            if ';' in s:
-                name, time = s.split(';')
-                add(executable, name, time)
+        return out
+
+
+# XXX: Find a better place to put this
+def update_image(executable):
+    print "Updating image ..."
+    with open('update.st', 'w') as f:
+        f.write('''Smalltalk snapshot: true andQuit: true.''')
+    print executable.run(["-vm-display-X11", "-headless", "images/%s" % SqueakImage, "../update.st"])
+    os.remove('update.st')
+
+
+def find_cog_url():
+    baseurl = "http://www.mirandabanda.org/files/Cog/VM/"
+    r = urllib2.urlopen(baseurl)
+    ver = r.read().rsplit("VM.r", 1)[1].split("/", 1)[0]
+    vmfolder = "%s/VM.r%s/" % (baseurl, ver)
+    r = urllib2.urlopen(vmfolder).read()
+    off = r.find("coglinux")
+    filename = r[off:r.find(".tgz", off)] + ".tgz"
+    return ver, vmfolder + filename
+cogid, cogurl = find_cog_url()
+
+
+Cog = Project(
+    "squeak",
+    executables=[
+        Executable(
+            "cogvm",
+            "coglinux/squeak",
+            cogurl,
+            callback=update_image
+        )
+    ],
+    arguments=['-vm-display-X11', '-headless', "images/%s.image" % SqueakImage, '../benchmarks.st'],
+    commitid=cogid
+)
+RSqueakVM = Project(
+    "lang-smalltalk",
+    executables=[
+        Executable("targetimageloadingsmalltalk-c", "./targetimageloadingsmalltalk-c")
+    ],
+    arguments=["images/%s.image" % SqueakImage, '-m', 'runSPyBenchmarks']
+)
+
 
 if __name__ == "__main__":
-    download_prerequesites()
-    run()
+    for project in [Cog, RSqueakVM]:
+        project.post_results()


More information about the pypy-commit mailing list