From 837131cbd4c43659471f00b39656fc58fb20a923 Mon Sep 17 00:00:00 2001 From: Anatoly Bubenkov Date: Sun, 18 Jan 2015 01:21:33 +0100 Subject: [PATCH] add chdir to change directory on remote side. fix dependency --- CHANGES.rst | 2 +- README.rst | 4 ++++ pytest_cloud/__init__.py | 2 +- pytest_cloud/plugin.py | 35 +++++++++++++++++++++++++++-------- setup.py | 3 ++- tests/test_plugin.py | 17 +++++++++-------- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7fbccd0..7c0f2df 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -1.0.1 +1.0.2 ----- - Initial public release diff --git a/README.rst b/README.rst index ae3391a..bf21e36 100644 --- a/README.rst +++ b/README.rst @@ -47,6 +47,10 @@ Command-line options * `--cloud-node` Node host name to run tests on. Multiple allowed. +* `--cloud-chdir` + Optional relative path to be used on the remote test nodes as target folder for syncing file and run tests. + Default is `pytest__`. + * `--cloud-virtualenv-path` Optional relative path to the virtualenv to be used on the remote test nodes. diff --git a/pytest_cloud/__init__.py b/pytest_cloud/__init__.py index cd7ca49..a6221b3 100644 --- a/pytest_cloud/__init__.py +++ b/pytest_cloud/__init__.py @@ -1 +1 @@ -__version__ = '1.0.1' +__version__ = '1.0.2' diff --git a/pytest_cloud/plugin.py b/pytest_cloud/plugin.py index 562262e..54381a1 100644 --- a/pytest_cloud/plugin.py +++ b/pytest_cloud/plugin.py @@ -3,6 +3,7 @@ Provides an easy way of running tests amoung several test nodes (slaves). """ from __future__ import division +import os.path import itertools import math @@ -32,9 +33,18 @@ def pytest_configure(config): config.pluginmanager.register(SplinterXdistPlugin()) -def pytest_addoption(parser): # pragma: no cover +def pytest_addoption(parser): """Pytest hook to add custom command line option(s).""" group = parser.getgroup("cloud", "distributed tests scheduler") + group._addoption( + '--cloud-chdir', + action="store", dest="cloud_chdir", + default=os.path.join( + 'pytest', + os.environ['USER'], + os.path.basename(os.environ['PWD']) + ).replace(os.path.sep, '_'), + help="relative path on remote node to run tests in. Default is pytest__") group.addoption( "--cloud-node", help="test node to use for distributed testing", type='string', action="append", @@ -96,7 +106,7 @@ def get_node_capabilities(channel): channel.send(caps) -def get_node_specs(node, host, caps, mem_per_process=None, max_processes=None): +def get_node_specs(node, host, caps, chdir=None, mem_per_process=None, max_processes=None): """Get single node specs. Executed on the master node side. @@ -105,6 +115,8 @@ def get_node_specs(node, host, caps, mem_per_process=None, max_processes=None): :type node: str :param host: hostname of the node :type host: str + :param chdir: relative path where to run (and sync) tests on the remote side + :type chdir: str :param mem_per_process: optional amount of memory per process needed, in megabytest :type mem_per_process: int :param max_processes: optional maximum number of processes per test node @@ -117,15 +129,16 @@ def get_node_specs(node, host, caps, mem_per_process=None, max_processes=None): if mem_per_process: count = min(int(math.floor(caps['virtual_memory']['free'] / mem_per_process)), count) return ( - '1*ssh={node}//id={host}:{index}'.format( + '1*ssh={node}//id={host}:{index}//chdir={chdir}'.format( count=count, node=node, host=host, - index=index) + index=index, + chdir=chdir) for index in range(count)) -def get_nodes_specs(nodes, virtualenv_path=None, mem_per_process=None, max_processes=None): +def get_nodes_specs(nodes, chdir=None, virtualenv_path=None, mem_per_process=None, max_processes=None): """Get nodes specs. Get list of node names, connect to each of them, get the system information, produce the list of node specs out of @@ -134,6 +147,8 @@ def get_nodes_specs(nodes, virtualenv_path=None, mem_per_process=None, max_proce :param nodes: `list` of node names in form [[@], ...] :type nodes: list + :param chdir: relative path where to run (and sync) tests on the remote side + :type chdir: str :param virtualenv_path: relative path to the virtualenv to activate on the remote test node :type virtualenv_path: str :param mem_per_process: optional amount of memory per process needed, in megabytest @@ -152,9 +167,10 @@ def get_nodes_specs(nodes, virtualenv_path=None, mem_per_process=None, max_proce node_caps = {} for node in nodes: host = node.split('@')[1] if '@' in node else node - spec = 'ssh={node}//id={host}'.format( + spec = 'ssh={node}//id={host}//chdir={chdir}'.format( node=node, - host=host) + host=host, + chdir=chdir) try: gw = group.makegateway(spec) except Exception: @@ -174,7 +190,8 @@ def get_nodes_specs(nodes, virtualenv_path=None, mem_per_process=None, max_proce finally: multi_channel.waitclose() return list(itertools.chain.from_iterable( - get_node_specs(node, hst, node_caps[hst], mem_per_process=mem_per_process, max_processes=max_processes) + get_node_specs( + node, hst, node_caps[hst], chdir=chdir, mem_per_process=mem_per_process, max_processes=max_processes) for node, hst in node_specs) ) finally: @@ -188,8 +205,10 @@ def check_options(config): if mem_per_process: mem_per_process = mem_per_process * 1024 * 1024 virtualenv_path = config.option.cloud_virtualenv_path + chdir = config.option.cloud_chdir node_specs = get_nodes_specs( config.option.cloud_nodes, + chdir=chdir, virtualenv_path=virtualenv_path, max_processes=config.option.cloud_max_processes, mem_per_process=mem_per_process) diff --git a/setup.py b/setup.py index 22ed9e4..8623b8d 100755 --- a/setup.py +++ b/setup.py @@ -52,9 +52,10 @@ def run_tests(self): include_package_data=True, url='https://github.com/pytest-dev/pytest-cloud', install_requires=[ - 'setuptools', + 'psutil', 'pytest', 'pytest-xdist', + 'setuptools', 'six', ], classifiers=[ diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 60517b0..6adcf80 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -12,31 +12,31 @@ None, None, [ - '1*ssh=1.example.com//id=1.example.com:0', - '1*ssh=1.example.com//id=1.example.com:1', - '1*ssh=user@2.example.com//id=2.example.com:0', + '1*ssh=1.example.com//id=1.example.com:0//chdir=pytest_', + '1*ssh=1.example.com//id=1.example.com:1//chdir=pytest_', + '1*ssh=user@2.example.com//id=2.example.com:0//chdir=pytest_', ]), ('1.example.com', '', 2, 100, '2.example.com', 'user', 1, 200, 200, None, [ - '1*ssh=user@2.example.com//id=2.example.com:0', + '1*ssh=user@2.example.com//id=2.example.com:0//chdir=pytest_', ]), ('1.example.com', '', 2, 100, '2.example.com', 'user', 1, 200, None, 1, [ - '1*ssh=1.example.com//id=1.example.com:0', - '1*ssh=user@2.example.com//id=2.example.com:0', + '1*ssh=1.example.com//id=1.example.com:0//chdir=pytest_', + '1*ssh=user@2.example.com//id=2.example.com:0//chdir=pytest_', ]), ('1.example.com', '', 2, 100, '2.example.com', 'user', 1, 200, 200, 1, [ - '1*ssh=user@2.example.com//id=2.example.com:0', + '1*ssh=user@2.example.com//id=2.example.com:0//chdir=pytest_', ]), ] ) @@ -69,6 +69,7 @@ def test_schedule( assert mocked_rsync.return_value.add_target.call_args[0][1] == '.env' assert mocked_rsync.return_value.send.called config = mocked_dsession.call_args[0][0] - assert config.option.tx == result + for spec, expected in zip(config.option.tx, result): + assert spec.startswith(expected) assert config.option.dist == 'load' assert config.option.rsyncdir == ['.env']