summaryrefslogtreecommitdiff
path: root/admin/test_release.py
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-09-19 22:32:00 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-09-19 22:32:00 -0400
commite1824d6af15fa442b2df86c5b216503d6c17a2ff (patch)
treeb4d25bfdb201414896a43de3d2eff4fdd7d0f8df /admin/test_release.py
parentb9bec0304a8c40f483c0a6f48e7f3c510768a3b3 (diff)
downloadpasslib-e1824d6af15fa442b2df86c5b216503d6c17a2ff.tar.gz
added some scripts used during release management
Diffstat (limited to 'admin/test_release.py')
-rw-r--r--admin/test_release.py256
1 files changed, 256 insertions, 0 deletions
diff --git a/admin/test_release.py b/admin/test_release.py
new file mode 100644
index 0000000..d62e18b
--- /dev/null
+++ b/admin/test_release.py
@@ -0,0 +1,256 @@
+"""helper script that tries to build & test passlib for various python versions.
+
+note that this script is very Linux-specific,
+and in fact contains various hardcoded assumptions
+that are only true for the systems used by passlib's developers.
+
+it also calls "rm -rf" a lot, so be wary :)
+"""
+#=========================================================================
+# imports
+#=========================================================================
+import re
+import sys
+import os.path
+import subprocess
+
+#=========================================================================
+# helpers
+#=========================================================================
+def absjoin(*args):
+ return os.path.abspath(os.path.join(*args))
+
+def discard_paths(*paths, **kwds):
+ cmd = [ "rm", "-rf" ]
+ if kwds.get("sudo"):
+ cmd.insert(0, "sudo")
+ paths = filter(os.path.exists, paths)
+ if paths:
+ subprocess.check_call(cmd + list(paths))
+
+#=========================================================================
+# main
+#=========================================================================
+class PlatformTestApp(object):
+ "command line program that runs passlib's unittest suite for all python versions"
+
+ #=========================================================================
+ # class attrs
+ #=========================================================================
+ # names of vms to test
+ vm_names = [
+ # normal python versions
+ "2.5",
+ "2.6",
+ "2.7",
+ "3.1",
+ "3.2",
+
+ # other vms
+ "y2.7-1.5", # pypy 1.5
+ "y2.7-1.6", # pypy 1.6
+ "j2.5", # jython 2.5
+ "gae",
+ ]
+
+ #=========================================================================
+ # instance attrs
+ #=========================================================================
+ root_dir = None # root dir of source
+ version = None #current version string
+ sdist_dir = None # unpacked sdist dir
+
+ #=========================================================================
+ # init
+ #=========================================================================
+ def __init__(self, args):
+ self.args = args
+
+ #=========================================================================
+ # run
+ #=========================================================================
+ def run(self):
+ # change dir root dir
+ self.root_dir = absjoin(__file__, os.pardir, os.pardir)
+ os.chdir(self.root_dir)
+
+ # get version
+ self.version = subprocess.check_output(
+ ["python", "setup.py","--version"]).strip()
+
+ # purge build & dist
+ discard_paths(
+ absjoin(self.root_dir, "dist"),
+ absjoin(self.root_dir, "build"),
+ )
+
+ # create new source dist, extract it, and work from that
+ subprocess.check_call(["python", "setup.py", "sdist"])
+ os.chdir(absjoin(self.root_dir, "dist"))
+ subprocess.check_call(["tar", "zxvf", "passlib-" + self.version + ".tar.gz"])
+ self.sdist_dir = absjoin(self.root_dir, "dist", "passlib-" + self.version)
+
+ # run test for each of the vms
+ for name in self.vm_names:
+ self.run_vm_test(name)
+
+ return 0
+
+ def run_vm_test(self, name):
+ # cd to sdist dir, purge everything
+ os.chdir(self.sdist_dir)
+ discard_paths(
+ absjoin(self.sdist_dir, "dist"),
+ absjoin(self.sdist_dir, "build"),
+ )
+ self.uninstall_passlib(name)
+
+ # if gae, run unittests directly in source
+ if name == "gae":
+ self.run_gae_test()
+ else:
+ self.run_vm_test_egg(name)
+ if not self.parse_vm(name)[0]:
+ self.uninstall_passlib(name)
+ self.run_vm_test_pip(name)
+
+ self.uninstall_passlib(name)
+
+ def run_gae_test(self):
+ # cd to preconfigured gae app
+ gae_dir = absjoin(self.root_dir, os.pardir, "gae")
+ os.chdir(gae_dir)
+
+ # cleanup and init symlink for passlib
+ target_dir = absjoin(gae_dir, "passlib")
+ discard_paths(target_dir)
+ os.symlink(absjoin(self.sdist_dir, "passlib"), target_dir)
+
+ # run nose w/ gae integration
+ subprocess.check_call([
+ self.get_vm_exe("gae", "nosetests"),
+ "--with-gae",
+ "--exe", # later versions set exe bit on test_xxx.py files
+ "--tests", "passlib/tests",
+ ])
+
+ def run_vm_test_pip(self, name):
+ os.chdir(absjoin(self.root_dir, "dist"))
+
+ # install via pip
+ pkg = "passlib-" + self.version + ".tar.gz"
+ if self.is_vm_sitewide(name):
+ subprocess.check_call([
+ "sudo",
+ self.get_vm_exe(name, "pip"),
+ "install",
+ pkg,
+ ])
+ else:
+ subprocess.check_call([
+ self.get_vm_exe(name, "pip"),
+ "install", "--user",
+ pkg,
+ ])
+
+ # cd to install location and run tests
+ # NOTE: just testing that pip worked, so skipping expensive tests
+ os.chdir(absjoin(self.get_vm_dir(name)))
+ subprocess.check_call([
+ self.get_vm_exe(name, "nosetests"),
+ "--exe", # later versions set exe bit on test_xxx.py files
+ "--tests", "passlib/tests/test_context.py",
+ ])
+
+ def run_vm_test_egg(self, name):
+
+ # build & install egg
+ subprocess.check_call([
+ self.get_vm_exe(name, "python"),
+ "setup.py",
+ "bdist_egg",
+ ])
+ egg_name = "passlib-%s-py%s.egg" % (self.version, self.get_vm_suffix(name))
+ exe = self.get_vm_exe(name, "easy_install")
+ if self.is_vm_sitewide(name):
+ subprocess.check_call(["sudo", exe, "dist/" + egg_name])
+ else:
+ subprocess.check_call([exe, "--user", "dist/" + egg_name])
+
+ # cd to install location and run tests
+ os.chdir(absjoin(self.get_vm_dir(name), egg_name))
+ subprocess.check_call([
+ self.get_vm_exe(name, "nosetests"),
+ "--exe", # later versions set exe bit on test_xxx.py files
+ "--tests", "passlib/tests",
+ ])
+
+ def uninstall_passlib(self, name):
+ vm_dir = self.get_vm_dir(name)
+ discard_paths(*[
+ absjoin(vm_dir, fname)
+ for fname in os.listdir(vm_dir)
+ if fname.startswith("passlib")
+ ], sudo=self.is_vm_sitewide(name))
+
+ #=========================================================================
+ # vm info
+ #=========================================================================
+ def parse_vm(self, name):
+ "parse 'vm name' string into (vm id, py version, vm release)"
+ if name == "gae":
+ name = "2.5"
+ m = re.match(r"^(?P<vm>[a-z]*)(?P<ver>[\d.]+)(-(?P<rel>[\d.]+))?$", name)
+ if not m:
+ raise ValueError("can't parse vm name: %r" % (name,))
+ return m.group("vm", "ver", "rel")
+
+ def is_vm_sitewide(self, name):
+ "does vm require installing site-wide?"
+ vm, ver, rel = self.parse_vm(name)
+ return vm == "y" or ver == "2.5"
+
+ def get_vm_suffix(self, name):
+ "return suffix used by egg built using specified vm"
+ return self.parse_vm(name)[1]
+
+ def get_vm_dir(self, name):
+ "get name of dir where eggs will be installed for specified vm"
+ vm, ver, rel = self.parse_vm(name)
+ if vm == "y":
+ return "/opt/pypy-" + rel + "/site-packages"
+ elif vm in ["j", ""] and ver == "2.5":
+ prefix = "/usr/lib"
+ else:
+ prefix = os.path.expanduser("~/.local/lib")
+ return prefix + "/python" + self.get_vm_suffix(name) + "/site-packages"
+
+ def get_vm_exe(self, name, exe):
+ "return path to appropriate exe for specified vm"
+ vm, ver, rel = self.parse_vm(name)
+ if vm:
+ if vm == "y":
+ if exe == "python":
+ exe = "pypy"
+ return "/opt/pypy-" + rel + "/bin/" + exe
+ elif vm == "j" and exe == "python":
+ return "jython"
+ else:
+ return exe + "-" + name
+ else:
+ if exe == "python":
+ return "python" + ver
+ else:
+ return exe + "-" + ver
+
+ #=========================================================================
+ # eoc
+ #=========================================================================
+
+if __name__ == "__main__":
+ app = PlatformTestApp(sys.argv[1:])
+ sys.exit(app.run())
+
+#=========================================================================
+# eof
+#=========================================================================