Skip to content

Instantly share code, notes, and snippets.

@harlowja
Created June 9, 2014 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harlowja/b0b6e2590bf140c6f792 to your computer and use it in GitHub Desktop.
Save harlowja/b0b6e2590bf140c6f792 to your computer and use it in GitHub Desktop.
Remote tox tester
import argparse
import getpass
import os
import select
import socket
import sys
import tarfile
import tempfile
import threading
import time
import fcntl
from fcntl import F_GETFL, F_SETFL
from os import O_NONBLOCK
import six
import plumbum
from plumbum import local
from plumbum.path import utils
DEF_VENV = 'py27'
def read_write(read_from, write_where, chunk_size=128):
while True:
try:
data = os.read(read_from.fileno(), chunk_size)
if len(data):
write_where.write(data)
write_where.flush()
else:
break
except OSError:
break
def spinning_cursor():
while True:
for ch in '|/-\\':
yield ch
def runner(cmd, args):
p = cmd.popen(args=tuple(args))
flags = fcntl.fcntl(p.stdout, F_GETFL)
fcntl.fcntl(p.stdout, F_SETFL, flags | O_NONBLOCK)
flags = fcntl.fcntl(p.stderr, F_GETFL)
fcntl.fcntl(p.stderr, F_SETFL, flags | O_NONBLOCK)
inputs = [p.stdout, p.stderr]
inputs_outputs = {
p.stdout: sys.stdout,
p.stderr: sys.stderr,
}
spinner = spinning_cursor()
while p.poll() == None:
i_ready, o_ready, e_ready = select.select(inputs, [], [], 0.05)
for s in i_ready:
read_write(s, inputs_outputs[s])
sys.stdout.write(spinner.next())
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
# Ensure everything is read (just incase).
for (innie, outtie) in six.iteritems(inputs_outputs):
read_write(innie, outtie)
return p.returncode
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose",
help="increase output verbosity",
action="store_true", default=False)
default_source_dir = os.getcwd()
parser.add_argument("-d", "--directory",
help="test directory"
" (default: %s)" % default_source_dir,
action="store", default=default_source_dir,
metavar="DIR")
default_hostname = socket.gethostname()
parser.add_argument("--host",
help="remote test"
" host (default: %s)" % default_hostname,
action="store", metavar="HOST",
default=default_hostname)
default_user = getpass.getuser()
parser.add_argument("-u", "--user",
help="remote test"
" user (default: %s)" % default_user,
action="store", metavar="USER", default=default_user)
parser.add_argument("--venv",
help="remote test"
" venv (default: %s)" % DEF_VENV,
action="store", metavar="VENV",
default=DEF_VENV)
default_test_dir = os.path.expanduser("~/.testing")
parser.add_argument("--path",
help="remote test"
" path (default: %s)" % default_test_dir,
action="store", metavar="DIR",
default=default_test_dir)
args = parser.parse_args()
src_path = args.directory
src = local.path(src_path)
user = args.user
host = args.host
path = args.path
if not os.path.exists(os.path.join(src_path, "tox.ini")):
print("No tox.ini file available. This will not end well.")
return 1
print("-" * 70)
print("Connecting to %s@%s..." % (user, host))
with plumbum.SshMachine(host=host, user=user) as m:
with tempfile.NamedTemporaryFile(suffix=".%s.tar" % src.basename) as fh:
tarball = tarfile.open(fileobj=fh, mode='w')
try:
print("Tarring up %s -> %s..." % (src, fh.name))
for (dirpath, dirnames, filenames) in os.walk(src_path):
for name in filenames:
path = os.path.join(dirpath, name)
if not path.startswith(src_path):
print("Invalid path '%s' found" % (path))
return 1
arcname = path[len(src_path):]
if args.verbose:
print('Adding %s as %s' % (path, arcname))
tarball.add(path, arcname=arcname)
finally:
tarball.close()
fh.flush()
mk = m['mkdir']
base = m.path(args.path)
if not base.exists:
mk("-p", base)
target = base / src.basename
if target.exists:
print("Removing old %s..." % (target))
rm = m['rm']
rm("-rf", target)
mk("-p", target)
tar_target = target / os.path.split(fh.name)[1]
print("Copying %s to %s..." % (fh.name, tar_target))
utils.copy(fh.name, tar_target)
with m.cwd(target):
print("Extracting %s..." % (tar_target))
e = m['tar']
e('-xf', tar_target.basename)
print('Running tox with venv %s...' % (args.venv))
print("-" * 70)
with m.cwd(target):
tox_args = ["-e%s" % args.venv]
if args.verbose:
tox_args.append("-v")
rc = runner(m['tox'], tox_args)
return rc
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment