summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorholger krekel <holger@merlinux.eu>2015-04-20 21:51:46 +0200
committerholger krekel <holger@merlinux.eu>2015-04-20 21:51:46 +0200
commit5460ace40a08b880ebce23cee9d62f2d4999790f (patch)
tree34fc4948097489ba6df6834665640dd85d127ea0
parent406d45d0ef7a5c7baab6db6621dadc5c2c6822a3 (diff)
downloadtox-5460ace40a08b880ebce23cee9d62f2d4999790f.tar.gz
introduce new "platform" setting for tox
(XXX) consider using environment marker syntax
-rw-r--r--CHANGELOG8
-rw-r--r--doc/config.txt6
-rw-r--r--doc/example/basic.txt13
-rw-r--r--tests/test_config.py46
-rw-r--r--tests/test_z_cmdline.py18
-rw-r--r--tox/_cmdline.py6
-rw-r--r--tox/_config.py18
-rw-r--r--tox/_venv.py4
-rw-r--r--tox/interpreters.py6
9 files changed, 117 insertions, 8 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c935cdd..7865ef7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,11 @@
-dev
+2.0.dev1
-----------
--
+- introduce a way to specify on which platform a testenvironment is to
+ execute: the new per-environment "platform" setting allows to specify
+ a regular expression which is matched against sys.platform.
+ If platform is set and doesn't match the test environment the
+ test environment is ignored, no setup or tests are attempted.
1.9.2
diff --git a/doc/config.txt b/doc/config.txt
index b5a717f..a7702ac 100644
--- a/doc/config.txt
+++ b/doc/config.txt
@@ -155,6 +155,12 @@ Complete list of settings that you can put into ``testenv*`` sections:
(Experimentally introduced in 1.6.1) all installer commands are executed
using the ``{toxinidir}`` as the current working directory.
+.. confval:: platform=REGEX
+
+ A testenv can define a new ``platform`` setting as a regular expression.
+ If a non-empty expression is defined and does not match against the
+ ``sys.platform`` string the test environment will be skipped.
+
.. confval:: setenv=MULTI-LINE-LIST
.. versionadded:: 0.9
diff --git a/doc/example/basic.txt b/doc/example/basic.txt
index e0dbece..b88b28c 100644
--- a/doc/example/basic.txt
+++ b/doc/example/basic.txt
@@ -46,6 +46,19 @@ Available "default" test environments names are::
However, you can also create your own test environment names,
see some of the examples in :doc:`examples <../examples>`.
+specifying a platform
+-----------------------------------------------
+
+.. versionadded:: 2.0
+
+If you want to specify which platform(s) your test environment
+runs on you can set a platform regular expression like this::
+
+ platform = linux2|darwin
+
+If the expression does not match against ``sys.platform``
+the test environment will be skipped.
+
whitelisting non-virtualenv commands
-----------------------------------------------
diff --git a/tests/test_config.py b/tests/test_config.py
index f957771..758db48 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -7,6 +7,7 @@ import tox
import tox._config
from tox._config import * # noqa
from tox._config import _split_env
+from tox._venv import VirtualEnv
class TestVenvConfig:
@@ -18,6 +19,7 @@ class TestVenvConfig:
assert config.toxworkdir.realpath() == tmpdir.join(".tox").realpath()
assert config.envconfigs['py1'].basepython == sys.executable
assert config.envconfigs['py1'].deps == []
+ assert not config.envconfigs['py1'].platform
def test_config_parsing_multienv(self, tmpdir, newconfig):
config = newconfig([], """
@@ -98,6 +100,50 @@ class TestVenvConfig:
assert parseini._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3<=2.0')
assert not parseini._is_same_dep('pkg_hello-world3==1.0', 'otherpkg>=2.0')
+
+class TestConfigPlatform:
+ def test_config_parse_platform(self, newconfig):
+ config = newconfig([], """
+ [testenv:py1]
+ platform = linux2
+ """)
+ assert len(config.envconfigs) == 1
+ assert config.envconfigs['py1'].platform == "linux2"
+
+ def test_config_parse_platform_rex(self, newconfig, mocksession, monkeypatch):
+ config = newconfig([], """
+ [testenv:py1]
+ platform = a123|b123
+ """)
+ assert len(config.envconfigs) == 1
+ envconfig = config.envconfigs['py1']
+ venv = VirtualEnv(envconfig, session=mocksession)
+ assert not venv.matching_platform()
+ monkeypatch.setattr(sys, "platform", "a123")
+ assert venv.matching_platform()
+ monkeypatch.setattr(sys, "platform", "b123")
+ assert venv.matching_platform()
+ monkeypatch.undo()
+ assert not venv.matching_platform()
+
+
+ @pytest.mark.parametrize("plat", ["win", "lin", ])
+ def test_config_parse_platform_with_factors(self, newconfig, plat, monkeypatch):
+ monkeypatch.setattr(sys, "platform", "win32")
+ config = newconfig([], """
+ [tox]
+ envlist = py27-{win,lin,osx}
+ [testenv]
+ platform =
+ win: win32
+ lin: linux2
+ """)
+ assert len(config.envconfigs) == 3
+ platform = config.envconfigs['py27-' + plat].platform
+ expected = {"win": "win32", "lin": "linux2"}.get(plat)
+ assert platform == expected
+
+
class TestConfigPackage:
def test_defaults(self, tmpdir, newconfig):
config = newconfig([], "")
diff --git a/tests/test_z_cmdline.py b/tests/test_z_cmdline.py
index 0c145be..391bc4b 100644
--- a/tests/test_z_cmdline.py
+++ b/tests/test_z_cmdline.py
@@ -242,6 +242,24 @@ def test_unknown_interpreter(cmd, initproj):
"*ERROR*InterpreterNotFound*xyz_unknown_interpreter*",
])
+def test_skip_platform_mismatch(cmd, initproj):
+ initproj("interp123-0.5", filedefs={
+ 'tests': {'test_hello.py': "def test_hello(): pass"},
+ 'tox.ini': '''
+ [testenv]
+ changedir=tests
+ platform=x123
+ '''
+ })
+ result = cmd.run("tox")
+ assert not result.ret
+ assert "platform mismatch" not in result.stdout.str()
+ result = cmd.run("tox", "-v")
+ assert not result.ret
+ result.stdout.fnmatch_lines([
+ "*python*platform mismatch*"
+ ])
+
def test_skip_unknown_interpreter(cmd, initproj):
initproj("interp123-0.5", filedefs={
'tests': {'test_hello.py': "def test_hello(): pass"},
diff --git a/tox/_cmdline.py b/tox/_cmdline.py
index 14eb685..4037283 100644
--- a/tox/_cmdline.py
+++ b/tox/_cmdline.py
@@ -474,6 +474,9 @@ class Session:
if self.config.option.sdistonly:
return
for venv in self.venvlist:
+ if not venv.matching_platform():
+ venv.status = "platform mismatch"
+ continue # we simply omit non-matching platforms
if self.setupenv(venv):
if venv.envconfig.develop:
self.developpkg(venv, self.config.setupdir)
@@ -505,6 +508,9 @@ class Session:
else:
retcode = 1
self.report.error(msg)
+ elif status == "platform mismatch":
+ msg = " %s: %s" %(venv.envconfig.envname, str(status))
+ self.report.verbosity1(msg)
elif status and status != "skipped tests":
msg = " %s: %s" %(venv.envconfig.envname, str(status))
self.report.error(msg)
diff --git a/tox/_config.py b/tox/_config.py
index 3d26686..b9ffc62 100644
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -151,9 +151,11 @@ class Config(object):
homedir = self.toxinidir # XXX good idea?
return homedir
+
class VenvConfig:
- def __init__(self, **kw):
- self.__dict__.update(kw)
+ def __init__(self, envname, config):
+ self.envname = envname
+ self.config = config
@property
def envbindir(self):
@@ -195,6 +197,8 @@ class VenvConfig:
"python2.5 is not supported anymore, sorry")
return info.executable
+
+
testenvprefix = "testenv:"
def get_homedir():
@@ -321,8 +325,7 @@ class parseini:
return factors
def _makeenvconfig(self, name, section, subs, config):
- vc = VenvConfig(envname=name)
- vc.config = config
+ vc = VenvConfig(config=config, envname=name)
factors = set(name.split('-'))
reader = IniReader(self._cfg, fallbacksections=["testenv"],
factors=factors)
@@ -381,6 +384,13 @@ class parseini:
ixserver = None
name = self._replace_forced_dep(name, config)
vc.deps.append(DepConfig(name, ixserver))
+
+ platform = ""
+ for platform in reader.getlist(section, "platform"):
+ if platform.strip():
+ break
+ vc.platform = platform
+
vc.distribute = reader.getbool(section, "distribute", False)
vc.sitepackages = self.config.option.sitepackages or \
reader.getbool(section, "sitepackages", False)
diff --git a/tox/_venv.py b/tox/_venv.py
index 65eb73b..eff932d 100644
--- a/tox/_venv.py
+++ b/tox/_venv.py
@@ -1,5 +1,6 @@
from __future__ import with_statement
import sys, os
+import re
import codecs
import py
import tox
@@ -171,6 +172,9 @@ class VirtualEnv(object):
def getsupportedinterpreter(self):
return self.envconfig.getsupportedinterpreter()
+ def matching_platform(self):
+ return re.match(self.envconfig.platform, sys.platform)
+
def create(self, action=None):
#if self.getcommandpath("activate").dirpath().check():
# return
diff --git a/tox/interpreters.py b/tox/interpreters.py
index 75318c5..241651f 100644
--- a/tox/interpreters.py
+++ b/tox/interpreters.py
@@ -90,11 +90,12 @@ class ExecFailed(Exception):
class InterpreterInfo:
runnable = True
- def __init__(self, name, executable, version_info):
+ def __init__(self, name, executable, version_info, sysplatform):
assert executable and version_info
self.name = name
self.executable = executable
self.version_info = version_info
+ self.sysplatform = sysplatform
def __str__(self):
return "<executable at %s, version_info %s>" % (
@@ -163,7 +164,8 @@ else:
def pyinfo():
import sys
- return dict(version_info=tuple(sys.version_info))
+ return dict(version_info=tuple(sys.version_info),
+ sysplatform=sys.platform)
def sitepackagesdir(envdir):
from distutils.sysconfig import get_python_lib