summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorholger krekel <holger@merlinux.eu>2015-04-21 11:51:10 +0200
committerholger krekel <holger@merlinux.eu>2015-04-21 11:51:10 +0200
commitb38964389b2df20c166df11906d77a3f7d56ab76 (patch)
treeb5ae245140aea4867135b245d698316483348a4c
parent5460ace40a08b880ebce23cee9d62f2d4999790f (diff)
downloadtox-b38964389b2df20c166df11906d77a3f7d56ab76.tar.gz
trying out isolating env variables
-rw-r--r--CHANGELOG20
-rw-r--r--doc/config.txt14
-rw-r--r--doc/example/basic.txt16
-rw-r--r--setup.cfg2
-rw-r--r--setup.py2
-rw-r--r--tests/test_config.py37
-rw-r--r--tests/test_venv.py11
-rw-r--r--tox/__init__.py2
-rw-r--r--tox/_config.py12
-rw-r--r--tox/_venv.py5
10 files changed, 110 insertions, 11 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 7865ef7..f537931 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,11 +1,21 @@
-2.0.dev1
+2.0.0.dev1
-----------
-- introduce a way to specify on which platform a testenvironment is to
- execute: the new per-environment "platform" setting allows to specify
+- (new) introduce environment variable isolation:
+ tox now only passes the PATH variable from the tox
+ invocation environment to the test environment and on Windows
+ also ``SYSTEMROOT`` and ``PATHEXT``. If you need to pass through further
+ environment variables you can use the new ``passenv`` setting,
+ a space-separated list of environment variable names. Each name
+ can make use of fnmatch-style glob patterns. All environment
+ variables which exist in the tox-invocation environment will be copied
+ to the test environment.
+
+- (new) introduce a way to specify on which platform a testenvironment is to
+ execute: the new per-venv "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.
+ If platform is set and doesn't match the platform spec in 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 a7702ac..04f1678 100644
--- a/doc/config.txt
+++ b/doc/config.txt
@@ -169,6 +169,20 @@ Complete list of settings that you can put into ``testenv*`` sections:
will be used for all test command invocations as well as for installing
the sdist package into a virtual environment.
+.. confval:: passenv=SPACE-SEPARATED-GLOBNAMES
+
+ .. versionadded:: 2.0
+
+ A list of wildcard environment variable names which
+ shall be copied from the tox invocation environment to the test
+ environment. If a specified environment variable doesn't exist in the tox
+ invocation environment it is ignored. You can use ``*`` and ``?`` to
+ match multiple environment variables with one name.
+
+ Note that the ``PATH`` variable is unconditionally passed down and on
+ Windows ``SYSTEMROOT`` and ``PATHEXT`` will be passed down as well.
+ You can override these variables with the ``setenv`` option.
+
.. confval:: recreate=True|False(default)
Always recreate virtual environment if this option is True.
diff --git a/doc/example/basic.txt b/doc/example/basic.txt
index b88b28c..f4df233 100644
--- a/doc/example/basic.txt
+++ b/doc/example/basic.txt
@@ -173,6 +173,22 @@ To force tox to recreate a (particular) virtual environment::
would trigger a complete reinstallation of the existing py27 environment
(or create it afresh if it doesn't exist).
+passing down environment variables
+-------------------------------------------
+
+.. versionadded:: 2.0
+
+By default tox will only pass the ``PATH`` environment variable (and on
+windows ``SYSTEMROOT`` and ``PATHEXT``) from the tox invocation to the
+test environments. If you want to pass down additional environment
+variables you can use the ``passenv`` option::
+
+ [testenv]
+ passenv = LANG
+
+When your test commands execute they will execute with
+the same LANG setting as the one with which tox was invoked.
+
setting environment variables
-------------------------------------------
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..3c6e79c
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal=1
diff --git a/setup.py b/setup.py
index ec27f73..82c45db 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@ def main():
description='virtualenv-based automation of test activities',
long_description=open("README.rst").read(),
url='http://tox.testrun.org/',
- version='1.9.3.dev1',
+ version='2.0.0.dev1',
license='http://opensource.org/licenses/MIT',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
author='holger krekel',
diff --git a/tests/test_config.py b/tests/test_config.py
index 758db48..122cbc5 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -642,6 +642,43 @@ class TestConfigTestEnv:
assert envconfig.setenv['PYTHONPATH'] == 'something'
assert envconfig.setenv['ANOTHER_VAL'] == 'else'
+ @pytest.mark.parametrize("plat", ["win32", "linux2"])
+ def test_passenv(self, tmpdir, newconfig, monkeypatch, plat):
+ monkeypatch.setattr(sys, "platform", plat)
+ monkeypatch.setenv("A123A", "a")
+ monkeypatch.setenv("A123B", "b")
+ monkeypatch.setenv("BX23", "0")
+ config = newconfig("""
+ [testenv]
+ passenv = A123* B?23
+ """)
+ assert len(config.envconfigs) == 1
+ envconfig = config.envconfigs['python']
+ if plat == "win32":
+ assert "PATHEXT" in envconfig.passenv
+ assert "SYSTEMROOT" in envconfig.passenv
+ assert "PATH" in envconfig.passenv
+ assert "A123A" in envconfig.passenv
+ assert "A123B" in envconfig.passenv
+
+ def test_passenv_with_factor(self, tmpdir, newconfig, monkeypatch):
+ monkeypatch.setenv("A123A", "a")
+ monkeypatch.setenv("A123B", "b")
+ monkeypatch.setenv("BX23", "0")
+ config = newconfig("""
+ [tox]
+ envlist = {x1,x2}
+ [testenv]
+ passenv =
+ x1: A123A
+ x2: A123B
+ """)
+ assert len(config.envconfigs) == 2
+ assert "A123A" in config.envconfigs["x1"].passenv
+ assert "A123B" not in config.envconfigs["x1"].passenv
+ assert "A123B" in config.envconfigs["x2"].passenv
+ assert "A123A" not in config.envconfigs["x2"].passenv
+
def test_changedir_override(self, tmpdir, newconfig):
config = newconfig("""
[testenv]
diff --git a/tests/test_venv.py b/tests/test_venv.py
index 3faa16b..3a3689c 100644
--- a/tests/test_venv.py
+++ b/tests/test_venv.py
@@ -517,11 +517,13 @@ class TestVenvTest:
assert 'PIP_REQUIRE_VIRTUALENV' not in os.environ
assert '__PYVENV_LAUNCHER__' not in os.environ
-def test_setenv_added_to_pcall(tmpdir, mocksession, newconfig):
+def test_env_variables_added_to_pcall(tmpdir, mocksession, newconfig, monkeypatch):
pkg = tmpdir.ensure("package.tar.gz")
+ monkeypatch.setenv("X123", "123")
config = newconfig([], """
[testenv:python]
commands=python -V
+ passenv = X123
setenv =
ENV_VAR = value
""")
@@ -540,9 +542,12 @@ def test_setenv_added_to_pcall(tmpdir, mocksession, newconfig):
assert 'ENV_VAR' in env
assert env['ENV_VAR'] == 'value'
assert env['VIRTUAL_ENV'] == str(venv.path)
+ assert env['X123'] == "123"
- for e in os.environ:
- assert e in env
+ assert set(env) == set(["ENV_VAR", "VIRTUAL_ENV", "PYTHONHASHSEED",
+ "X123", "PATH"])
+ #for e in os.environ:
+ # assert e in env
def test_installpkg_no_upgrade(tmpdir, newmocksession):
pkg = tmpdir.ensure("package.tar.gz")
diff --git a/tox/__init__.py b/tox/__init__.py
index c206441..95f2dfb 100644
--- a/tox/__init__.py
+++ b/tox/__init__.py
@@ -1,5 +1,5 @@
#
-__version__ = '1.9.3.dev1'
+__version__ = '2.0.0.dev1'
class exception:
class Error(Exception):
diff --git a/tox/_config.py b/tox/_config.py
index b9ffc62..2fae46a 100644
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -1,6 +1,7 @@
import argparse
import os
import random
+from fnmatch import fnmatchcase
import sys
import re
import shlex
@@ -366,6 +367,17 @@ class parseini:
if config.hashseed is not None:
setenv['PYTHONHASHSEED'] = config.hashseed
setenv.update(reader.getdict(section, 'setenv'))
+
+ # read passenv
+ vc.passenv = set(["PATH"])
+ if sys.platform == "win32":
+ vc.passenv.add("SYSTEMROOT") # needed for python's crypto module
+ vc.passenv.add("PATHEXT") # needed for discovering executables
+ for spec in reader.getlist(section, "passenv", sep=" "):
+ for name in os.environ:
+ if fnmatchcase(name, spec):
+ vc.passenv.add(name)
+
vc.setenv = setenv
if not vc.setenv:
vc.setenv = None
diff --git a/tox/_venv.py b/tox/_venv.py
index eff932d..8666785 100644
--- a/tox/_venv.py
+++ b/tox/_venv.py
@@ -326,7 +326,10 @@ class VirtualEnv(object):
action=action, extraenv=extraenv)
def _getenv(self, extraenv={}):
- env = os.environ.copy()
+ env = {}
+ for envname in self.envconfig.passenv:
+ if envname in os.environ:
+ env[envname] = os.environ[envname]
setenv = self.envconfig.setenv
if setenv:
env.update(setenv)