diff options
author | Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> | 2016-09-17 20:30:13 +0200 |
---|---|---|
committer | Ronny Pfannschmidt <opensource@ronnypfannschmidt.de> | 2016-09-17 20:30:13 +0200 |
commit | 07fdce28e407b0ec10b5fee682f134550eae335b (patch) | |
tree | 74baed3d9a1daa2ecd8d4bb3f00ff1e47c9f88d4 /tests/test_config.py | |
parent | 2237fc53240f8892577b3a54016dfcfe8be7fd56 (diff) | |
download | tox-master.tar.gz |
Diffstat (limited to 'tests/test_config.py')
-rw-r--r-- | tests/test_config.py | 2060 |
1 files changed, 0 insertions, 2060 deletions
diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index d685ac8..0000000 --- a/tests/test_config.py +++ /dev/null @@ -1,2060 +0,0 @@ -import sys -from textwrap import dedent - -import py -import pytest -import tox -import tox.config -from tox.config import * # noqa -from tox.venv import VirtualEnv - - -class TestVenvConfig: - def test_config_parsing_minimal(self, tmpdir, newconfig): - config = newconfig([], """ - [testenv:py1] - """) - assert len(config.envconfigs) == 1 - assert config.toxworkdir.realpath() == tmpdir.join(".tox").realpath() - assert config.envconfigs['py1'].basepython == sys.executable - assert config.envconfigs['py1'].deps == [] - assert config.envconfigs['py1'].platform == ".*" - - def test_config_parsing_multienv(self, tmpdir, newconfig): - config = newconfig([], """ - [tox] - toxworkdir = %s - indexserver = - xyz = xyz_repo - [testenv:py1] - deps=hello - [testenv:py2] - deps= - world1 - :xyz:http://hello/world - """ % (tmpdir, )) - assert config.toxworkdir == tmpdir - assert len(config.envconfigs) == 2 - assert config.envconfigs['py1'].envdir == tmpdir.join("py1") - dep = config.envconfigs['py1'].deps[0] - assert dep.name == "hello" - assert dep.indexserver is None - assert config.envconfigs['py2'].envdir == tmpdir.join("py2") - dep1, dep2 = config.envconfigs['py2'].deps - assert dep1.name == "world1" - assert dep2.name == "http://hello/world" - assert dep2.indexserver.name == "xyz" - assert dep2.indexserver.url == "xyz_repo" - - def test_envdir_set_manually(self, tmpdir, newconfig): - config = newconfig([], """ - [testenv:devenv] - envdir = devenv - """) - envconfig = config.envconfigs['devenv'] - assert envconfig.envdir == tmpdir.join('devenv') - - def test_envdir_set_manually_with_substitutions(self, tmpdir, newconfig): - config = newconfig([], """ - [testenv:devenv] - envdir = {toxworkdir}/foobar - """) - envconfig = config.envconfigs['devenv'] - assert envconfig.envdir == config.toxworkdir.join('foobar') - - def test_force_dep_version(self, initproj): - """ - Make sure we can override dependencies configured in tox.ini when using the command line - option --force-dep. - """ - initproj("example123-0.5", filedefs={ - 'tox.ini': ''' - [tox] - - [testenv] - deps= - dep1==1.0 - dep2>=2.0 - dep3 - dep4==4.0 - ''' - }) - config = parseconfig( - ['--force-dep=dep1==1.5', '--force-dep=dep2==2.1', - '--force-dep=dep3==3.0']) - assert config.option.force_dep == [ - 'dep1==1.5', 'dep2==2.1', 'dep3==3.0'] - assert [str(x) for x in config.envconfigs['python'].deps] == [ - 'dep1==1.5', 'dep2==2.1', 'dep3==3.0', 'dep4==4.0', - ] - - def test_force_dep_with_url(self, initproj): - initproj("example123-0.5", filedefs={ - 'tox.ini': ''' - [tox] - - [testenv] - deps= - dep1==1.0 - https://pypi.python.org/xyz/pkg1.tar.gz - ''' - }) - config = parseconfig( - ['--force-dep=dep1==1.5']) - assert config.option.force_dep == [ - 'dep1==1.5' - ] - assert [str(x) for x in config.envconfigs['python'].deps] == [ - 'dep1==1.5', 'https://pypi.python.org/xyz/pkg1.tar.gz' - ] - - def test_is_same_dep(self): - """ - Ensure correct parseini._is_same_dep is working with a few samples. - """ - assert DepOption._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3') - assert DepOption._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3>=2.0') - assert DepOption._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3>2.0') - assert DepOption._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3<2.0') - assert DepOption._is_same_dep('pkg_hello-world3==1.0', 'pkg_hello-world3<=2.0') - assert not DepOption._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([], "") - assert config.setupdir.realpath() == tmpdir.realpath() - assert config.toxworkdir.realpath() == tmpdir.join(".tox").realpath() - envconfig = config.envconfigs['python'] - assert envconfig.args_are_paths - assert not envconfig.recreate - assert not envconfig.pip_pre - - def test_defaults_distshare(self, tmpdir, newconfig): - config = newconfig([], "") - assert config.distshare == config.homedir.join(".tox", "distshare") - - def test_defaults_changed_dir(self, tmpdir, newconfig): - tmpdir.mkdir("abc").chdir() - config = newconfig([], "") - assert config.setupdir.realpath() == tmpdir.realpath() - assert config.toxworkdir.realpath() == tmpdir.join(".tox").realpath() - - def test_project_paths(self, tmpdir, newconfig): - config = newconfig(""" - [tox] - toxworkdir=%s - """ % tmpdir) - assert config.toxworkdir == tmpdir - - -class TestParseconfig: - def test_search_parents(self, tmpdir): - b = tmpdir.mkdir("a").mkdir("b") - toxinipath = tmpdir.ensure("tox.ini") - old = b.chdir() - try: - config = parseconfig([]) - finally: - old.chdir() - assert config.toxinipath == toxinipath - - -def test_get_homedir(monkeypatch): - monkeypatch.setattr(py.path.local, "_gethomedir", - classmethod(lambda x: {}[1])) - assert not get_homedir() - monkeypatch.setattr(py.path.local, "_gethomedir", - classmethod(lambda x: 0 / 0)) - assert not get_homedir() - monkeypatch.setattr(py.path.local, "_gethomedir", - classmethod(lambda x: "123")) - assert get_homedir() == "123" - - -class TestGetcontextname: - def test_blank(self, monkeypatch): - monkeypatch.setattr(os, "environ", {}) - assert getcontextname() is None - - def test_jenkins(self, monkeypatch): - monkeypatch.setattr(os, "environ", {"JENKINS_URL": "xyz"}) - assert getcontextname() == "jenkins" - - def test_hudson_legacy(self, monkeypatch): - monkeypatch.setattr(os, "environ", {"HUDSON_URL": "xyz"}) - assert getcontextname() == "jenkins" - - -class TestIniParserAgainstCommandsKey: - """Test parsing commands with substitutions""" - - def test_command_substitution_from_other_section(self, newconfig): - config = newconfig(""" - [section] - key = whatever - [testenv] - commands = - echo {[section]key} - """) - reader = SectionReader("testenv", config._cfg) - x = reader.getargvlist("commands") - assert x == [["echo", "whatever"]] - - def test_command_substitution_from_other_section_multiline(self, newconfig): - """Ensure referenced multiline commands form from other section injected - as multiple commands.""" - config = newconfig(""" - [section] - commands = - cmd1 param11 param12 - # comment is omitted - cmd2 param21 \ - param22 - [base] - commands = cmd 1 \ - 2 3 4 - cmd 2 - [testenv] - commands = - {[section]commands} - {[section]commands} - # comment is omitted - echo {[base]commands} - """) - reader = SectionReader("testenv", config._cfg) - x = reader.getargvlist("commands") - assert x == [ - "cmd1 param11 param12".split(), - "cmd2 param21 param22".split(), - "cmd1 param11 param12".split(), - "cmd2 param21 param22".split(), - ["echo", "cmd", "1", "2", "3", "4", "cmd", "2"], - ] - - def test_command_substitution_from_other_section_posargs(self, newconfig): - """Ensure subsitition from other section with posargs succeeds""" - config = newconfig(""" - [section] - key = thing {posargs} arg2 - [testenv] - commands = - {[section]key} - """) - reader = SectionReader("testenv", config._cfg) - reader.addsubstitutions([r"argpos"]) - x = reader.getargvlist("commands") - assert x == [['thing', 'argpos', 'arg2']] - - def test_command_section_and_posargs_substitution(self, newconfig): - """Ensure subsitition from other section with posargs succeeds""" - config = newconfig(""" - [section] - key = thing arg1 - [testenv] - commands = - {[section]key} {posargs} endarg - """) - reader = SectionReader("testenv", config._cfg) - reader.addsubstitutions([r"argpos"]) - x = reader.getargvlist("commands") - assert x == [['thing', 'arg1', 'argpos', 'endarg']] - - def test_command_env_substitution(self, newconfig): - """Ensure referenced {env:key:default} values are substituted correctly.""" - config = newconfig(""" - [testenv:py27] - setenv = - TEST=testvalue - commands = - ls {env:TEST} - """) - envconfig = config.envconfigs["py27"] - assert envconfig.commands == [["ls", "testvalue"]] - assert envconfig.setenv["TEST"] == "testvalue" - - -class TestIniParser: - def test_getstring_single(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key=value - """) - reader = SectionReader("section", config._cfg) - x = reader.getstring("key") - assert x == "value" - assert not reader.getstring("hello") - x = reader.getstring("hello", "world") - assert x == "world" - - def test_missing_substitution(self, tmpdir, newconfig): - config = newconfig(""" - [mydefault] - key2={xyz} - """) - reader = SectionReader("mydefault", config._cfg, fallbacksections=['mydefault']) - assert reader is not None - with py.test.raises(tox.exception.ConfigError): - reader.getstring("key2") - - def test_getstring_fallback_sections(self, tmpdir, newconfig): - config = newconfig(""" - [mydefault] - key2=value2 - [section] - key=value - """) - reader = SectionReader("section", config._cfg, fallbacksections=['mydefault']) - x = reader.getstring("key2") - assert x == "value2" - x = reader.getstring("key3") - assert not x - x = reader.getstring("key3", "world") - assert x == "world" - - def test_getstring_substitution(self, tmpdir, newconfig): - config = newconfig(""" - [mydefault] - key2={value2} - [section] - key={value} - """) - reader = SectionReader("section", config._cfg, fallbacksections=['mydefault']) - reader.addsubstitutions(value="newvalue", value2="newvalue2") - x = reader.getstring("key2") - assert x == "newvalue2" - x = reader.getstring("key3") - assert not x - x = reader.getstring("key3", "{value2}") - assert x == "newvalue2" - - def test_getlist(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - item1 - {item2} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(item1="not", item2="grr") - x = reader.getlist("key2") - assert x == ['item1', 'grr'] - - def test_getdict(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - key1=item1 - key2={item2} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(item1="not", item2="grr") - x = reader.getdict("key2") - assert 'key1' in x - assert 'key2' in x - assert x['key1'] == 'item1' - assert x['key2'] == 'grr' - - x = reader.getdict("key3", {1: 2}) - assert x == {1: 2} - - def test_getstring_environment_substitution(self, monkeypatch, newconfig): - monkeypatch.setenv("KEY1", "hello") - config = newconfig(""" - [section] - key1={env:KEY1} - key2={env:KEY2} - """) - reader = SectionReader("section", config._cfg) - x = reader.getstring("key1") - assert x == "hello" - with py.test.raises(tox.exception.ConfigError): - reader.getstring("key2") - - def test_getstring_environment_substitution_with_default(self, monkeypatch, newconfig): - monkeypatch.setenv("KEY1", "hello") - config = newconfig(""" - [section] - key1={env:KEY1:DEFAULT_VALUE} - key2={env:KEY2:DEFAULT_VALUE} - key3={env:KEY3:} - """) - reader = SectionReader("section", config._cfg) - x = reader.getstring("key1") - assert x == "hello" - x = reader.getstring("key2") - assert x == "DEFAULT_VALUE" - x = reader.getstring("key3") - assert x == "" - - def test_value_matches_section_substituion(self): - assert is_section_substitution("{[setup]commands}") - - def test_value_doesn_match_section_substitution(self): - assert is_section_substitution("{[ ]commands}") is None - assert is_section_substitution("{[setup]}") is None - assert is_section_substitution("{[setup] commands}") is None - - def test_getstring_other_section_substitution(self, newconfig): - config = newconfig(""" - [section] - key = rue - [testenv] - key = t{[section]key} - """) - reader = SectionReader("testenv", config._cfg) - x = reader.getstring("key") - assert x == "true" - - def test_argvlist(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - cmd1 {item1} {item2} - cmd2 {item2} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(item1="with space", item2="grr") - # py.test.raises(tox.exception.ConfigError, - # "reader.getargvlist('key1')") - assert reader.getargvlist('key1') == [] - x = reader.getargvlist("key2") - assert x == [["cmd1", "with", "space", "grr"], - ["cmd2", "grr"]] - - def test_argvlist_windows_escaping(self, tmpdir, newconfig): - config = newconfig(""" - [section] - comm = py.test {posargs} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions([r"hello\this"]) - argv = reader.getargv("comm") - assert argv == ["py.test", "hello\\this"] - - def test_argvlist_multiline(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - cmd1 {item1} \ - {item2} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(item1="with space", item2="grr") - # py.test.raises(tox.exception.ConfigError, - # "reader.getargvlist('key1')") - assert reader.getargvlist('key1') == [] - x = reader.getargvlist("key2") - assert x == [["cmd1", "with", "space", "grr"]] - - def test_argvlist_quoting_in_command(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key1= - cmd1 'part one' \ - 'part two' - """) - reader = SectionReader("section", config._cfg) - x = reader.getargvlist("key1") - assert x == [["cmd1", "part one", "part two"]] - - def test_argvlist_comment_after_command(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key1= - cmd1 --flag # run the flag on the command - """) - reader = SectionReader("section", config._cfg) - x = reader.getargvlist("key1") - assert x == [["cmd1", "--flag"]] - - def test_argvlist_command_contains_hash(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key1= - cmd1 --re "use the # symbol for an arg" - """) - reader = SectionReader("section", config._cfg) - x = reader.getargvlist("key1") - assert x == [["cmd1", "--re", "use the # symbol for an arg"]] - - def test_argvlist_positional_substitution(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - cmd1 [] - cmd2 {posargs:{item2} \ - other} - """) - reader = SectionReader("section", config._cfg) - posargs = ['hello', 'world'] - reader.addsubstitutions(posargs, item2="value2") - # py.test.raises(tox.exception.ConfigError, - # "reader.getargvlist('key1')") - assert reader.getargvlist('key1') == [] - argvlist = reader.getargvlist("key2") - assert argvlist[0] == ["cmd1"] + posargs - assert argvlist[1] == ["cmd2"] + posargs - - reader = SectionReader("section", config._cfg) - reader.addsubstitutions([], item2="value2") - # py.test.raises(tox.exception.ConfigError, - # "reader.getargvlist('key1')") - assert reader.getargvlist('key1') == [] - argvlist = reader.getargvlist("key2") - assert argvlist[0] == ["cmd1"] - assert argvlist[1] == ["cmd2", "value2", "other"] - - def test_argvlist_quoted_posargs(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - cmd1 --foo-args='{posargs}' - cmd2 -f '{posargs}' - cmd3 -f {posargs} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(["foo", "bar"]) - assert reader.getargvlist('key1') == [] - x = reader.getargvlist("key2") - assert x == [["cmd1", "--foo-args=foo bar"], - ["cmd2", "-f", "foo bar"], - ["cmd3", "-f", "foo", "bar"]] - - def test_argvlist_posargs_with_quotes(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key2= - cmd1 -f {posargs} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(["foo", "'bar", "baz'"]) - assert reader.getargvlist('key1') == [] - x = reader.getargvlist("key2") - assert x == [["cmd1", "-f", "foo", "bar baz"]] - - def test_positional_arguments_are_only_replaced_when_standing_alone(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key= - cmd0 [] - cmd1 -m '[abc]' - cmd2 -m '\'something\'' [] - cmd3 something[]else - """) - reader = SectionReader("section", config._cfg) - posargs = ['hello', 'world'] - reader.addsubstitutions(posargs) - - argvlist = reader.getargvlist('key') - assert argvlist[0] == ['cmd0'] + posargs - assert argvlist[1] == ['cmd1', '-m', '[abc]'] - assert argvlist[2] == ['cmd2', '-m', "something"] + posargs - assert argvlist[3] == ['cmd3', 'something[]else'] - - def test_substitution_with_multiple_words(self, newconfig): - inisource = """ - [section] - key = py.test -n5 --junitxml={envlogdir}/junit-{envname}.xml [] - """ - config = newconfig(inisource) - reader = SectionReader("section", config._cfg) - posargs = ['hello', 'world'] - reader.addsubstitutions(posargs, envlogdir='ENV_LOG_DIR', envname='ENV_NAME') - - expected = [ - 'py.test', '-n5', '--junitxml=ENV_LOG_DIR/junit-ENV_NAME.xml', 'hello', 'world' - ] - assert reader.getargvlist('key')[0] == expected - - def test_getargv(self, newconfig): - config = newconfig(""" - [section] - key=some command "with quoting" - """) - reader = SectionReader("section", config._cfg) - expected = ['some', 'command', 'with quoting'] - assert reader.getargv('key') == expected - - def test_getpath(self, tmpdir, newconfig): - config = newconfig(""" - [section] - path1={HELLO} - """) - reader = SectionReader("section", config._cfg) - reader.addsubstitutions(toxinidir=tmpdir, HELLO="mypath") - x = reader.getpath("path1", tmpdir) - assert x == tmpdir.join("mypath") - - def test_getbool(self, tmpdir, newconfig): - config = newconfig(""" - [section] - key1=True - key2=False - key1a=true - key2a=falsE - key5=yes - """) - reader = SectionReader("section", config._cfg) - assert reader.getbool("key1") is True - assert reader.getbool("key1a") is True - assert reader.getbool("key2") is False - assert reader.getbool("key2a") is False - py.test.raises(KeyError, 'reader.getbool("key3")') - py.test.raises(tox.exception.ConfigError, 'reader.getbool("key5")') - - -class TestIniParserPrefix: - def test_basic_section_access(self, tmpdir, newconfig): - config = newconfig(""" - [p:section] - key=value - """) - reader = SectionReader("section", config._cfg, prefix="p") - x = reader.getstring("key") - assert x == "value" - assert not reader.getstring("hello") - x = reader.getstring("hello", "world") - assert x == "world" - - def test_fallback_sections(self, tmpdir, newconfig): - config = newconfig(""" - [p:mydefault] - key2=value2 - [p:section] - key=value - """) - reader = SectionReader("section", config._cfg, prefix="p", - fallbacksections=['p:mydefault']) - x = reader.getstring("key2") - assert x == "value2" - x = reader.getstring("key3") - assert not x - x = reader.getstring("key3", "world") - assert x == "world" - - def test_value_matches_prefixed_section_substituion(self): - assert is_section_substitution("{[p:setup]commands}") - - def test_value_doesn_match_prefixed_section_substitution(self): - assert is_section_substitution("{[p: ]commands}") is None - assert is_section_substitution("{[p:setup]}") is None - assert is_section_substitution("{[p:setup] commands}") is None - - def test_other_section_substitution(self, newconfig): - config = newconfig(""" - [p:section] - key = rue - [p:testenv] - key = t{[p:section]key} - """) - reader = SectionReader("testenv", config._cfg, prefix="p") - x = reader.getstring("key") - assert x == "true" - - -class TestConfigTestEnv: - def test_commentchars_issue33(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] # hello - deps = http://abc#123 - commands= - python -c "x ; y" - """) - envconfig = config.envconfigs["python"] - assert envconfig.deps[0].name == "http://abc#123" - assert envconfig.commands[0] == ["python", "-c", "x ; y"] - - def test_defaults(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - commands= - xyz --abc - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert envconfig.commands == [["xyz", "--abc"]] - assert envconfig.changedir == config.setupdir - assert envconfig.sitepackages is False - assert envconfig.usedevelop is False - assert envconfig.ignore_errors is False - assert envconfig.envlogdir == envconfig.envdir.join("log") - assert list(envconfig.setenv.definitions.keys()) == ['PYTHONHASHSEED'] - hashseed = envconfig.setenv['PYTHONHASHSEED'] - assert isinstance(hashseed, str) - # The following line checks that hashseed parses to an integer. - int_hashseed = int(hashseed) - # hashseed is random by default, so we can't assert a specific value. - assert int_hashseed > 0 - assert envconfig.ignore_outcome is False - - def test_sitepackages_switch(self, tmpdir, newconfig): - config = newconfig(["--sitepackages"], "") - envconfig = config.envconfigs['python'] - assert envconfig.sitepackages is True - - def test_installpkg_tops_develop(self, newconfig): - config = newconfig(["--installpkg=abc"], """ - [testenv] - usedevelop = True - """) - assert not config.envconfigs["python"].usedevelop - - def test_specific_command_overrides(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - commands=xyz - [testenv:py] - commands=abc - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['py'] - assert envconfig.commands == [["abc"]] - - def test_whitelist_externals(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - whitelist_externals = xyz - commands=xyz - [testenv:x] - - [testenv:py] - whitelist_externals = xyz2 - commands=abc - """) - assert len(config.envconfigs) == 2 - envconfig = config.envconfigs['py'] - assert envconfig.commands == [["abc"]] - assert envconfig.whitelist_externals == ["xyz2"] - envconfig = config.envconfigs['x'] - assert envconfig.whitelist_externals == ["xyz"] - - def test_changedir(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - changedir=xyz - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert envconfig.changedir.basename == "xyz" - assert envconfig.changedir == config.toxinidir.join("xyz") - - def test_ignore_errors(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - ignore_errors=True - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert envconfig.ignore_errors is True - - def test_envbindir(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - basepython=python - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert envconfig.envpython == envconfig.envbindir.join("python") - - @pytest.mark.parametrize("bp", ["jython", "pypy", "pypy3"]) - def test_envbindir_jython(self, tmpdir, newconfig, bp): - config = newconfig(""" - [testenv] - basepython=%s - """ % bp) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - # on win32 and linux virtualenv uses "bin" for pypy/jython - assert envconfig.envbindir.basename == "bin" - if bp == "jython": - assert envconfig.envpython == envconfig.envbindir.join(bp) - - @pytest.mark.parametrize("plat", ["win32", "linux2"]) - def test_passenv_as_multiline_list(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* - # isolated comment - B?23 - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - if plat == "win32": - assert "PATHEXT" in envconfig.passenv - assert "SYSTEMDRIVE" in envconfig.passenv - assert "SYSTEMROOT" in envconfig.passenv - assert "TEMP" in envconfig.passenv - assert "TMP" in envconfig.passenv - else: - assert "TMPDIR" in envconfig.passenv - assert "PATH" in envconfig.passenv - assert "PIP_INDEX_URL" in envconfig.passenv - assert "LANG" in envconfig.passenv - assert "LD_LIBRARY_PATH" in envconfig.passenv - assert "A123A" in envconfig.passenv - assert "A123B" in envconfig.passenv - - @pytest.mark.parametrize("plat", ["win32", "linux2"]) - def test_passenv_as_space_separated_list(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 = - # comment - A123* B?23 - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - if plat == "win32": - assert "PATHEXT" in envconfig.passenv - assert "SYSTEMDRIVE" in envconfig.passenv - assert "SYSTEMROOT" in envconfig.passenv - assert "TEMP" in envconfig.passenv - assert "TMP" in envconfig.passenv - else: - assert "TMPDIR" in envconfig.passenv - assert "PATH" in envconfig.passenv - assert "PIP_INDEX_URL" in envconfig.passenv - assert "LANG" 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("A123C", "c") - monkeypatch.setenv("A123D", "d") - monkeypatch.setenv("BX23", "0") - monkeypatch.setenv("CCA43", "3") - monkeypatch.setenv("CB21", "4") - config = newconfig(""" - [tox] - envlist = {x1,x2} - [testenv] - passenv = - x1: A123A CC* - x1: CB21 - # passed to both environments - A123C - x2: A123B A123D - """) - assert len(config.envconfigs) == 2 - - assert "A123A" in config.envconfigs["x1"].passenv - assert "A123C" in config.envconfigs["x1"].passenv - assert "CCA43" in config.envconfigs["x1"].passenv - assert "CB21" in config.envconfigs["x1"].passenv - assert "A123B" not in config.envconfigs["x1"].passenv - assert "A123D" not in config.envconfigs["x1"].passenv - assert "BX23" not in config.envconfigs["x1"].passenv - - assert "A123B" in config.envconfigs["x2"].passenv - assert "A123D" in config.envconfigs["x2"].passenv - assert "A123A" not in config.envconfigs["x2"].passenv - assert "A123C" in config.envconfigs["x2"].passenv - assert "CCA43" not in config.envconfigs["x2"].passenv - assert "CB21" not in config.envconfigs["x2"].passenv - assert "BX23" not in config.envconfigs["x2"].passenv - - def test_passenv_from_global_env(self, tmpdir, newconfig, monkeypatch): - monkeypatch.setenv("A1", "a1") - monkeypatch.setenv("A2", "a2") - monkeypatch.setenv("TOX_TESTENV_PASSENV", "A1") - config = newconfig(""" - [testenv] - passenv = A2 - """) - env = config.envconfigs["python"] - assert "A1" in env.passenv - assert "A2" in env.passenv - - def test_changedir_override(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - changedir=xyz - [testenv:python] - changedir=abc - basepython=python2.6 - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert envconfig.changedir.basename == "abc" - assert envconfig.changedir == config.setupdir.join("abc") - - def test_install_command_setting(self, newconfig): - config = newconfig(""" - [testenv] - install_command=some_install {packages} - """) - envconfig = config.envconfigs['python'] - assert envconfig.install_command == [ - 'some_install', '{packages}'] - - def test_install_command_must_contain_packages(self, newconfig): - py.test.raises(tox.exception.ConfigError, newconfig, """ - [testenv] - install_command=pip install - """) - - def test_install_command_substitutions(self, newconfig): - config = newconfig(""" - [testenv] - install_command=some_install --arg={toxinidir}/foo \ - {envname} {opts} {packages} - """) - envconfig = config.envconfigs['python'] - assert envconfig.install_command == [ - 'some_install', '--arg=%s/foo' % config.toxinidir, 'python', - '{opts}', '{packages}'] - - def test_pip_pre(self, newconfig): - config = newconfig(""" - [testenv] - pip_pre=true - """) - envconfig = config.envconfigs['python'] - assert envconfig.pip_pre - - def test_pip_pre_cmdline_override(self, newconfig): - config = newconfig( - ['--pre'], - """ - [testenv] - pip_pre=false - """) - envconfig = config.envconfigs['python'] - assert envconfig.pip_pre - - def test_downloadcache(self, newconfig, monkeypatch): - monkeypatch.delenv("PIP_DOWNLOAD_CACHE", raising=False) - config = newconfig(""" - [testenv] - downloadcache=thecache - """) - envconfig = config.envconfigs['python'] - assert envconfig.downloadcache.basename == 'thecache' - - def test_downloadcache_env_override(self, newconfig, monkeypatch): - monkeypatch.setenv("PIP_DOWNLOAD_CACHE", 'fromenv') - config = newconfig(""" - [testenv] - downloadcache=somepath - """) - envconfig = config.envconfigs['python'] - assert envconfig.downloadcache.basename == "fromenv" - - def test_downloadcache_only_if_in_config(self, newconfig, tmpdir, - monkeypatch): - monkeypatch.setenv("PIP_DOWNLOAD_CACHE", tmpdir) - config = newconfig('') - envconfig = config.envconfigs['python'] - assert not envconfig.downloadcache - - def test_simple(tmpdir, newconfig): - config = newconfig(""" - [testenv:py26] - basepython=python2.6 - [testenv:py27] - basepython=python2.7 - """) - assert len(config.envconfigs) == 2 - assert "py26" in config.envconfigs - assert "py27" in config.envconfigs - - def test_substitution_error(tmpdir, newconfig): - py.test.raises(tox.exception.ConfigError, newconfig, """ - [testenv:py27] - basepython={xyz} - """) - - def test_substitution_defaults(tmpdir, newconfig): - config = newconfig(""" - [testenv:py27] - commands = - {toxinidir} - {toxworkdir} - {envdir} - {envbindir} - {envtmpdir} - {envpython} - {homedir} - {distshare} - {envlogdir} - """) - conf = config.envconfigs['py27'] - argv = conf.commands - assert argv[0][0] == config.toxinidir - assert argv[1][0] == config.toxworkdir - assert argv[2][0] == conf.envdir - assert argv[3][0] == conf.envbindir - assert argv[4][0] == conf.envtmpdir - assert argv[5][0] == conf.envpython - assert argv[6][0] == str(config.homedir) - assert argv[7][0] == config.homedir.join(".tox", "distshare") - assert argv[8][0] == conf.envlogdir - - def test_substitution_notfound_issue246(tmpdir, newconfig): - config = newconfig(""" - [testenv:py27] - setenv = - FOO={envbindir} - BAR={envsitepackagesdir} - """) - conf = config.envconfigs['py27'] - env = conf.setenv - assert 'FOO' in env - assert 'BAR' in env - - def test_substitution_positional(self, newconfig): - inisource = """ - [testenv:py27] - commands = - cmd1 [hello] \ - world - cmd1 {posargs:hello} \ - world - """ - conf = newconfig([], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "[hello]", "world"] - assert argv[1] == ["cmd1", "hello", "world"] - conf = newconfig(['brave', 'new'], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "[hello]", "world"] - assert argv[1] == ["cmd1", "brave", "new", "world"] - - def test_substitution_noargs_issue240(self, newconfig): - inisource = """ - [testenv] - commands = echo {posargs:foo} - """ - conf = newconfig([""], inisource).envconfigs['python'] - argv = conf.commands - assert argv[0] == ["echo"] - - def test_substitution_double(self, newconfig): - inisource = """ - [params] - foo = bah - foo2 = [params]foo - - [testenv:py27] - commands = - echo {{[params]foo2}} - """ - conf = newconfig([], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ['echo', 'bah'] - - def test_posargs_backslashed_or_quoted(self, tmpdir, newconfig): - inisource = """ - [testenv:py27] - commands = - echo "\{posargs\}" = {posargs} - echo "posargs = " "{posargs}" - """ - conf = newconfig([], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ['echo', '{posargs}', '='] - assert argv[1] == ['echo', 'posargs = ', ""] - - conf = newconfig(['dog', 'cat'], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ['echo', '{posargs}', '=', 'dog', 'cat'] - assert argv[1] == ['echo', 'posargs = ', 'dog cat'] - - def test_rewrite_posargs(self, tmpdir, newconfig): - inisource = """ - [testenv:py27] - args_are_paths = True - changedir = tests - commands = cmd1 {posargs:hello} - """ - conf = newconfig([], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "hello"] - - conf = newconfig(["tests/hello"], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "tests/hello"] - - tmpdir.ensure("tests", "hello") - conf = newconfig(["tests/hello"], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "hello"] - - def test_rewrite_simple_posargs(self, tmpdir, newconfig): - inisource = """ - [testenv:py27] - args_are_paths = True - changedir = tests - commands = cmd1 {posargs} - """ - conf = newconfig([], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1"] - - conf = newconfig(["tests/hello"], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "tests/hello"] - - tmpdir.ensure("tests", "hello") - conf = newconfig(["tests/hello"], inisource).envconfigs['py27'] - argv = conf.commands - assert argv[0] == ["cmd1", "hello"] - - @pytest.mark.parametrize('envlist, deps', [ - (['py27'], ('pytest', 'pytest-cov')), - (['py27', 'py34'], ('pytest', 'py{27,34}: pytest-cov')), - ]) - def test_take_dependencies_from_other_testenv( - self, - newconfig, - envlist, - deps - ): - inisource = """ - [tox] - envlist = {envlist} - [testenv] - deps={deps} - [testenv:py27] - deps= - {{[testenv]deps}} - fun - """.format( - envlist=','.join(envlist), - deps='\n' + '\n'.join([' ' * 17 + d for d in deps]) - ) - conf = newconfig([], inisource).envconfigs['py27'] - packages = [dep.name for dep in conf.deps] - assert packages == list(deps) + ['fun'] - - def test_take_dependencies_from_other_section(self, newconfig): - inisource = """ - [testing:pytest] - deps= - pytest - pytest-cov - [testing:mock] - deps= - mock - [testenv] - deps= - {[testing:pytest]deps} - {[testing:mock]deps} - fun - """ - conf = newconfig([], inisource) - env = conf.envconfigs['python'] - packages = [dep.name for dep in env.deps] - assert packages == ['pytest', 'pytest-cov', 'mock', 'fun'] - - def test_multilevel_substitution(self, newconfig): - inisource = """ - [testing:pytest] - deps= - pytest - pytest-cov - [testing:mock] - deps= - mock - - [testing] - deps= - {[testing:pytest]deps} - {[testing:mock]deps} - - [testenv] - deps= - {[testing]deps} - fun - """ - conf = newconfig([], inisource) - env = conf.envconfigs['python'] - packages = [dep.name for dep in env.deps] - assert packages == ['pytest', 'pytest-cov', 'mock', 'fun'] - - def test_recursive_substitution_cycle_fails(self, newconfig): - inisource = """ - [testing:pytest] - deps= - {[testing:mock]deps} - [testing:mock] - deps= - {[testing:pytest]deps} - - [testenv] - deps= - {[testing:pytest]deps} - """ - py.test.raises(ValueError, newconfig, [], inisource) - - def test_single_value_from_other_secton(self, newconfig, tmpdir): - inisource = """ - [common] - changedir = testing - [testenv] - changedir = {[common]changedir} - """ - conf = newconfig([], inisource).envconfigs['python'] - assert conf.changedir.basename == 'testing' - assert conf.changedir.dirpath().realpath() == tmpdir.realpath() - - def test_factors(self, newconfig): - inisource = """ - [tox] - envlist = a-x,b - - [testenv] - deps= - dep-all - a: dep-a - b: dep-b - x: dep-x - """ - conf = newconfig([], inisource) - configs = conf.envconfigs - assert [dep.name for dep in configs['a-x'].deps] == \ - ["dep-all", "dep-a", "dep-x"] - assert [dep.name for dep in configs['b'].deps] == ["dep-all", "dep-b"] - - def test_factor_ops(self, newconfig): - inisource = """ - [tox] - envlist = {a,b}-{x,y} - - [testenv] - deps= - a,b: dep-a-or-b - a-x: dep-a-and-x - {a,b}-y: dep-ab-and-y - """ - configs = newconfig([], inisource).envconfigs - get_deps = lambda env: [dep.name for dep in configs[env].deps] - assert get_deps("a-x") == ["dep-a-or-b", "dep-a-and-x"] - assert get_deps("a-y") == ["dep-a-or-b", "dep-ab-and-y"] - assert get_deps("b-x") == ["dep-a-or-b"] - assert get_deps("b-y") == ["dep-a-or-b", "dep-ab-and-y"] - - def test_default_factors(self, newconfig): - inisource = """ - [tox] - envlist = py{26,27,33,34}-dep - - [testenv] - deps= - dep: dep - """ - conf = newconfig([], inisource) - configs = conf.envconfigs - for name, config in configs.items(): - assert config.basepython == 'python%s.%s' % (name[2], name[3]) - - @pytest.mark.issue188 - def test_factors_in_boolean(self, newconfig): - inisource = """ - [tox] - envlist = py{27,33} - - [testenv] - recreate = - py27: True - """ - configs = newconfig([], inisource).envconfigs - assert configs["py27"].recreate - assert not configs["py33"].recreate - - @pytest.mark.issue190 - def test_factors_in_setenv(self, newconfig): - inisource = """ - [tox] - envlist = py27,py26 - - [testenv] - setenv = - py27: X = 1 - """ - configs = newconfig([], inisource).envconfigs - assert configs["py27"].setenv["X"] == "1" - assert "X" not in configs["py26"].setenv - - @pytest.mark.issue191 - def test_factor_use_not_checked(self, newconfig): - inisource = """ - [tox] - envlist = py27-{a,b} - - [testenv] - deps = b: test - """ - configs = newconfig([], inisource).envconfigs - assert set(configs.keys()) == set(['py27-a', 'py27-b']) - - @pytest.mark.issue198 - def test_factors_groups_touch(self, newconfig): - inisource = """ - [tox] - envlist = {a,b}{-x,} - - [testenv] - deps= - a,b,x,y: dep - """ - configs = newconfig([], inisource).envconfigs - assert set(configs.keys()) == set(['a', 'a-x', 'b', 'b-x']) - - def test_period_in_factor(self, newconfig): - inisource = """ - [tox] - envlist = py27-{django1.6,django1.7} - - [testenv] - deps = - django1.6: Django==1.6 - django1.7: Django==1.7 - """ - configs = newconfig([], inisource).envconfigs - assert sorted(configs) == ["py27-django1.6", "py27-django1.7"] - assert [d.name for d in configs["py27-django1.6"].deps] \ - == ["Django==1.6"] - - def test_ignore_outcome(self, newconfig): - inisource = """ - [testenv] - ignore_outcome=True - """ - config = newconfig([], inisource).envconfigs - assert config["python"].ignore_outcome is True - - -class TestGlobalOptions: - def test_notest(self, newconfig): - config = newconfig([], "") - assert not config.option.notest - config = newconfig(["--notest"], "") - assert config.option.notest - - def test_verbosity(self, newconfig): - config = newconfig([], "") - assert config.option.verbosity == 0 - config = newconfig(["-v"], "") - assert config.option.verbosity == 1 - config = newconfig(["-vv"], "") - assert config.option.verbosity == 2 - - def test_substitution_jenkins_default(self, tmpdir, - monkeypatch, newconfig): - monkeypatch.setenv("HUDSON_URL", "xyz") - config = newconfig(""" - [testenv:py27] - commands = - {distshare} - """) - conf = config.envconfigs['py27'] - argv = conf.commands - expect_path = config.toxworkdir.join("distshare") - assert argv[0][0] == expect_path - - def test_substitution_jenkins_context(self, tmpdir, monkeypatch, newconfig): - monkeypatch.setenv("HUDSON_URL", "xyz") - monkeypatch.setenv("WORKSPACE", tmpdir) - config = newconfig(""" - [tox:jenkins] - distshare = {env:WORKSPACE}/hello - [testenv:py27] - commands = - {distshare} - """) - conf = config.envconfigs['py27'] - argv = conf.commands - assert argv[0][0] == config.distshare - assert config.distshare == tmpdir.join("hello") - - def test_sdist_specification(self, tmpdir, newconfig): - config = newconfig(""" - [tox] - sdistsrc = {distshare}/xyz.zip - """) - assert config.sdistsrc == config.distshare.join("xyz.zip") - config = newconfig([], "") - assert not config.sdistsrc - - def test_env_selection(self, tmpdir, newconfig, monkeypatch): - inisource = """ - [tox] - envlist = py26 - [testenv:py26] - basepython=python2.6 - [testenv:py31] - basepython=python3.1 - [testenv:py27] - basepython=python2.7 - """ - # py.test.raises(tox.exception.ConfigError, - # "newconfig(['-exyz'], inisource)") - config = newconfig([], inisource) - assert config.envlist == ["py26"] - config = newconfig(["-epy31"], inisource) - assert config.envlist == ["py31"] - monkeypatch.setenv("TOXENV", "py31,py26") - config = newconfig([], inisource) - assert config.envlist == ["py31", "py26"] - monkeypatch.setenv("TOXENV", "ALL") - config = newconfig([], inisource) - assert config.envlist == ['py26', 'py27', 'py31'] - config = newconfig(["-eALL"], inisource) - assert config.envlist == ['py26', 'py27', 'py31'] - - def test_py_venv(self, tmpdir, newconfig, monkeypatch): - config = newconfig(["-epy"], "") - env = config.envconfigs['py'] - assert str(env.basepython) == sys.executable - - def test_default_environments(self, tmpdir, newconfig, monkeypatch): - envs = "py26,py27,py32,py33,py34,py35,py36,jython,pypy,pypy3" - inisource = """ - [tox] - envlist = %s - """ % envs - config = newconfig([], inisource) - envlist = envs.split(",") - assert config.envlist == envlist - for name in config.envlist: - env = config.envconfigs[name] - if name == "jython": - assert env.basepython == "jython" - elif name.startswith("pypy"): - assert env.basepython == name - else: - assert name.startswith("py") - bp = "python%s.%s" % (name[2], name[3]) - assert env.basepython == bp - - def test_envlist_expansion(self, newconfig): - inisource = """ - [tox] - envlist = py{26,27},docs - """ - config = newconfig([], inisource) - assert config.envlist == ["py26", "py27", "docs"] - - def test_envlist_cross_product(self, newconfig): - inisource = """ - [tox] - envlist = py{26,27}-dep{1,2} - """ - config = newconfig([], inisource) - assert config.envlist == \ - ["py26-dep1", "py26-dep2", "py27-dep1", "py27-dep2"] - - def test_envlist_multiline(self, newconfig): - inisource = """ - [tox] - envlist = - py27 - py34 - """ - config = newconfig([], inisource) - assert config.envlist == \ - ["py27", "py34"] - - def test_minversion(self, tmpdir, newconfig, monkeypatch): - inisource = """ - [tox] - minversion = 10.0 - """ - with py.test.raises(tox.exception.MinVersionError): - newconfig([], inisource) - - def test_skip_missing_interpreters_true(self, tmpdir, newconfig, monkeypatch): - inisource = """ - [tox] - skip_missing_interpreters = True - """ - config = newconfig([], inisource) - assert config.option.skip_missing_interpreters - - def test_skip_missing_interpreters_false(self, tmpdir, newconfig, monkeypatch): - inisource = """ - [tox] - skip_missing_interpreters = False - """ - config = newconfig([], inisource) - assert not config.option.skip_missing_interpreters - - def test_defaultenv_commandline(self, tmpdir, newconfig, monkeypatch): - config = newconfig(["-epy27"], "") - env = config.envconfigs['py27'] - assert env.basepython == "python2.7" - assert not env.commands - - def test_defaultenv_partial_override(self, tmpdir, newconfig, monkeypatch): - inisource = """ - [tox] - envlist = py27 - [testenv:py27] - commands= xyz - """ - config = newconfig([], inisource) - env = config.envconfigs['py27'] - assert env.basepython == "python2.7" - assert env.commands == [['xyz']] - - -class TestHashseedOption: - - def _get_envconfigs(self, newconfig, args=None, tox_ini=None, - make_hashseed=None): - if args is None: - args = [] - if tox_ini is None: - tox_ini = """ - [testenv] - """ - if make_hashseed is None: - make_hashseed = lambda: '123456789' - original_make_hashseed = tox.config.make_hashseed - tox.config.make_hashseed = make_hashseed - try: - config = newconfig(args, tox_ini) - finally: - tox.config.make_hashseed = original_make_hashseed - return config.envconfigs - - def _get_envconfig(self, newconfig, args=None, tox_ini=None): - envconfigs = self._get_envconfigs(newconfig, args=args, - tox_ini=tox_ini) - return envconfigs["python"] - - def _check_hashseed(self, envconfig, expected): - assert envconfig.setenv['PYTHONHASHSEED'] == expected - - def _check_testenv(self, newconfig, expected, args=None, tox_ini=None): - envconfig = self._get_envconfig(newconfig, args=args, tox_ini=tox_ini) - self._check_hashseed(envconfig, expected) - - def test_default(self, tmpdir, newconfig): - self._check_testenv(newconfig, '123456789') - - def test_passing_integer(self, tmpdir, newconfig): - args = ['--hashseed', '1'] - self._check_testenv(newconfig, '1', args=args) - - def test_passing_string(self, tmpdir, newconfig): - args = ['--hashseed', 'random'] - self._check_testenv(newconfig, 'random', args=args) - - def test_passing_empty_string(self, tmpdir, newconfig): - args = ['--hashseed', ''] - self._check_testenv(newconfig, '', args=args) - - @pytest.mark.xfail(sys.version_info >= (3, 2), - reason="at least Debian python 3.2/3.3 have a bug: " - "http://bugs.python.org/issue11884") - def test_passing_no_argument(self, tmpdir, newconfig): - """Test that passing no arguments to --hashseed is not allowed.""" - args = ['--hashseed'] - try: - self._check_testenv(newconfig, '', args=args) - except SystemExit: - e = sys.exc_info()[1] - assert e.code == 2 - return - assert False # getting here means we failed the test. - - def test_setenv(self, tmpdir, newconfig): - """Check that setenv takes precedence.""" - tox_ini = """ - [testenv] - setenv = - PYTHONHASHSEED = 2 - """ - self._check_testenv(newconfig, '2', tox_ini=tox_ini) - args = ['--hashseed', '1'] - self._check_testenv(newconfig, '2', args=args, tox_ini=tox_ini) - - def test_noset(self, tmpdir, newconfig): - args = ['--hashseed', 'noset'] - envconfig = self._get_envconfig(newconfig, args=args) - assert not envconfig.setenv.definitions - - def test_noset_with_setenv(self, tmpdir, newconfig): - tox_ini = """ - [testenv] - setenv = - PYTHONHASHSEED = 2 - """ - args = ['--hashseed', 'noset'] - self._check_testenv(newconfig, '2', args=args, tox_ini=tox_ini) - - def test_one_random_hashseed(self, tmpdir, newconfig): - """Check that different testenvs use the same random seed.""" - tox_ini = """ - [testenv:hash1] - [testenv:hash2] - """ - next_seed = [1000] - # This function is guaranteed to generate a different value each time. - - def make_hashseed(): - next_seed[0] += 1 - return str(next_seed[0]) - # Check that make_hashseed() works. - assert make_hashseed() == '1001' - envconfigs = self._get_envconfigs(newconfig, tox_ini=tox_ini, - make_hashseed=make_hashseed) - self._check_hashseed(envconfigs["hash1"], '1002') - # Check that hash2's value is not '1003', for example. - self._check_hashseed(envconfigs["hash2"], '1002') - - def test_setenv_in_one_testenv(self, tmpdir, newconfig): - """Check using setenv in one of multiple testenvs.""" - tox_ini = """ - [testenv:hash1] - setenv = - PYTHONHASHSEED = 2 - [testenv:hash2] - """ - envconfigs = self._get_envconfigs(newconfig, tox_ini=tox_ini) - self._check_hashseed(envconfigs["hash1"], '2') - self._check_hashseed(envconfigs["hash2"], '123456789') - - -class TestSetenv: - def test_getdict_lazy(self, tmpdir, newconfig, monkeypatch): - monkeypatch.setenv("X", "2") - config = newconfig(""" - [testenv:X] - key0 = - key1 = {env:X} - key2 = {env:Y:1} - """) - envconfig = config.envconfigs["X"] - val = envconfig._reader.getdict_setenv("key0") - assert val["key1"] == "2" - assert val["key2"] == "1" - - def test_getdict_lazy_update(self, tmpdir, newconfig, monkeypatch): - monkeypatch.setenv("X", "2") - config = newconfig(""" - [testenv:X] - key0 = - key1 = {env:X} - key2 = {env:Y:1} - """) - envconfig = config.envconfigs["X"] - val = envconfig._reader.getdict_setenv("key0") - d = {} - d.update(val) - assert d == {"key1": "2", "key2": "1"} - - def test_setenv_uses_os_environ(self, tmpdir, newconfig, monkeypatch): - monkeypatch.setenv("X", "1") - config = newconfig(""" - [testenv:env1] - setenv = - X = {env:X} - """) - assert config.envconfigs["env1"].setenv["X"] == "1" - - def test_setenv_default_os_environ(self, tmpdir, newconfig, monkeypatch): - monkeypatch.delenv("X", raising=False) - config = newconfig(""" - [testenv:env1] - setenv = - X = {env:X:2} - """) - assert config.envconfigs["env1"].setenv["X"] == "2" - - def test_setenv_uses_other_setenv(self, tmpdir, newconfig): - config = newconfig(""" - [testenv:env1] - setenv = - Y = 5 - X = {env:Y} - """) - assert config.envconfigs["env1"].setenv["X"] == "5" - - def test_setenv_recursive_direct(self, tmpdir, newconfig): - config = newconfig(""" - [testenv:env1] - setenv = - X = {env:X:3} - """) - assert config.envconfigs["env1"].setenv["X"] == "3" - - def test_setenv_overrides(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - setenv = - PYTHONPATH = something - ANOTHER_VAL=else - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert 'PYTHONPATH' in envconfig.setenv - assert 'ANOTHER_VAL' in envconfig.setenv - assert envconfig.setenv['PYTHONPATH'] == 'something' - assert envconfig.setenv['ANOTHER_VAL'] == 'else' - - def test_setenv_with_envdir_and_basepython(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - setenv = - VAL = {envdir} - basepython = {env:VAL} - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert 'VAL' in envconfig.setenv - assert envconfig.setenv['VAL'] == envconfig.envdir - assert envconfig.basepython == envconfig.envdir - - def test_setenv_ordering_1(self, tmpdir, newconfig): - config = newconfig(""" - [testenv] - setenv= - VAL={envdir} - commands=echo {env:VAL} - """) - assert len(config.envconfigs) == 1 - envconfig = config.envconfigs['python'] - assert 'VAL' in envconfig.setenv - assert envconfig.setenv['VAL'] == envconfig.envdir - assert str(envconfig.envdir) in envconfig.commands[0] - - def test_setenv_cross_section_subst_issue294(self, monkeypatch, newconfig): - """test that we can do cross-section substitution with setenv""" - monkeypatch.delenv('TEST', raising=False) - config = newconfig(""" - [section] - x = - NOT_TEST={env:TEST:defaultvalue} - - [testenv] - setenv = {[section]x} - """) - envconfig = config.envconfigs["python"] - assert envconfig.setenv["NOT_TEST"] == "defaultvalue" - - def test_setenv_cross_section_subst_twice(self, monkeypatch, newconfig): - """test that we can do cross-section substitution with setenv""" - monkeypatch.delenv('TEST', raising=False) - config = newconfig(""" - [section] - x = NOT_TEST={env:TEST:defaultvalue} - [section1] - y = {[section]x} - - [testenv] - setenv = {[section1]y} - """) - envconfig = config.envconfigs["python"] - assert envconfig.setenv["NOT_TEST"] == "defaultvalue" - - def test_setenv_cross_section_mixed(self, monkeypatch, newconfig): - """test that we can do cross-section substitution with setenv""" - monkeypatch.delenv('TEST', raising=False) - config = newconfig(""" - [section] - x = NOT_TEST={env:TEST:defaultvalue} - - [testenv] - setenv = {[section]x} - y = 7 - """) - envconfig = config.envconfigs["python"] - assert envconfig.setenv["NOT_TEST"] == "defaultvalue" - assert envconfig.setenv["y"] == "7" - - -class TestIndexServer: - def test_indexserver(self, tmpdir, newconfig): - config = newconfig(""" - [tox] - indexserver = - name1 = XYZ - name2 = ABC - """) - assert config.indexserver['default'].url is None - assert config.indexserver['name1'].url == "XYZ" - assert config.indexserver['name2'].url == "ABC" - - def test_parse_indexserver(self, newconfig): - inisource = """ - [tox] - indexserver = - default = http://pypi.testrun.org - name1 = whatever - """ - config = newconfig([], inisource) - assert config.indexserver['default'].url == "http://pypi.testrun.org" - assert config.indexserver['name1'].url == "whatever" - config = newconfig(['-i', 'qwe'], inisource) - assert config.indexserver['default'].url == "qwe" - assert config.indexserver['name1'].url == "whatever" - config = newconfig(['-i', 'name1=abc', '-i', 'qwe2'], inisource) - assert config.indexserver['default'].url == "qwe2" - assert config.indexserver['name1'].url == "abc" - - config = newconfig(["-i", "ALL=xzy"], inisource) - assert len(config.indexserver) == 2 - assert config.indexserver["default"].url == "xzy" - assert config.indexserver["name1"].url == "xzy" - - def test_multiple_homedir_relative_local_indexservers(self, newconfig): - inisource = """ - [tox] - indexserver = - default = file://{homedir}/.pip/downloads/simple - local1 = file://{homedir}/.pip/downloads/simple - local2 = file://{toxinidir}/downloads/simple - pypi = http://pypi.python.org/simple - """ - config = newconfig([], inisource) - expected = "file://%s/.pip/downloads/simple" % config.homedir - assert config.indexserver['default'].url == expected - assert config.indexserver['local1'].url == config.indexserver['default'].url - - -class TestParseEnv: - - def test_parse_recreate(self, newconfig): - inisource = "" - config = newconfig([], inisource) - assert not config.envconfigs['python'].recreate - config = newconfig(['--recreate'], inisource) - assert config.envconfigs['python'].recreate - config = newconfig(['-r'], inisource) - assert config.envconfigs['python'].recreate - inisource = """ - [testenv:hello] - recreate = True - """ - config = newconfig([], inisource) - assert config.envconfigs['hello'].recreate - - -class TestCmdInvocation: - def test_help(self, cmd): - result = cmd.run("tox", "-h") - assert not result.ret - result.stdout.fnmatch_lines([ - "*help*", - ]) - - def test_version(self, cmd): - result = cmd.run("tox", "--version") - assert not result.ret - stdout = result.stdout.str() - assert tox.__version__ in stdout - assert "imported from" in stdout - - def test_listenvs(self, cmd, initproj): - initproj('listenvs', filedefs={ - 'tox.ini': ''' - [tox] - envlist=py26,py27,py33,pypy,docs - - [testenv:notincluded] - changedir = whatever - - [testenv:docs] - changedir = docs - ''', - }) - result = cmd.run("tox", "-l") - result.stdout.fnmatch_lines(""" - *py26* - *py27* - *py33* - *pypy* - *docs* - """) - - def test_config_specific_ini(self, tmpdir, cmd): - ini = tmpdir.ensure("hello.ini") - result = cmd.run("tox", "-c", ini, "--showconfig") - assert not result.ret - result.stdout.fnmatch_lines([ - "*config-file*hello.ini*", - ]) - - def test_no_tox_ini(self, cmd, initproj): - initproj("noini-0.5", ) - result = cmd.run("tox") - assert result.ret - result.stderr.fnmatch_lines([ - "*ERROR*tox.ini*not*found*", - ]) - - def test_override_workdir(self, tmpdir, cmd, initproj): - baddir = "badworkdir-123" - gooddir = "overridden-234" - initproj("overrideworkdir-0.5", filedefs={ - 'tox.ini': ''' - [tox] - toxworkdir=%s - ''' % baddir, - }) - result = cmd.run("tox", "--workdir", gooddir, "--showconfig") - assert not result.ret - stdout = result.stdout.str() - assert gooddir in stdout - assert baddir not in stdout - assert py.path.local(gooddir).check() - assert not py.path.local(baddir).check() - - def test_showconfig_with_force_dep_version(self, cmd, initproj): - initproj('force_dep_version', filedefs={ - 'tox.ini': ''' - [tox] - - [testenv] - deps= - dep1==2.3 - dep2 - ''', - }) - result = cmd.run("tox", "--showconfig") - assert result.ret == 0 - result.stdout.fnmatch_lines([ - r'*deps*dep1==2.3, dep2*', - ]) - # override dep1 specific version, and force version for dep2 - result = cmd.run("tox", "--showconfig", "--force-dep=dep1", - "--force-dep=dep2==5.0") - assert result.ret == 0 - result.stdout.fnmatch_lines([ - r'*deps*dep1, dep2==5.0*', - ]) - - -@pytest.mark.parametrize("cmdline,envlist", [ - ("-e py26", ['py26']), - ("-e py26,py33", ['py26', 'py33']), - ("-e py26,py26", ['py26', 'py26']), - ("-e py26,py33 -e py33,py27", ['py26', 'py33', 'py33', 'py27']) -]) -def test_env_spec(cmdline, envlist): - args = cmdline.split() - config = parseconfig(args) - assert config.envlist == envlist - - -class TestCommandParser: - - def test_command_parser_for_word(self): - p = CommandParser('word') - # import pytest; pytest.set_trace() - assert list(p.words()) == ['word'] - - def test_command_parser_for_posargs(self): - p = CommandParser('[]') - assert list(p.words()) == ['[]'] - - def test_command_parser_for_multiple_words(self): - p = CommandParser('w1 w2 w3 ') - assert list(p.words()) == ['w1', ' ', 'w2', ' ', 'w3'] - - def test_command_parser_for_substitution_with_spaces(self): - p = CommandParser('{sub:something with spaces}') - assert list(p.words()) == ['{sub:something with spaces}'] - - def test_command_parser_with_complex_word_set(self): - complex_case = ( - 'word [] [literal] {something} {some:other thing} w{ord} w{or}d w{ord} ' - 'w{o:rd} w{o:r}d {w:or}d w[]ord {posargs:{a key}}') - p = CommandParser(complex_case) - parsed = list(p.words()) - expected = [ - 'word', ' ', '[]', ' ', '[literal]', ' ', '{something}', ' ', '{some:other thing}', - ' ', 'w', '{ord}', ' ', 'w', '{or}', 'd', ' ', 'w', '{ord}', ' ', 'w', '{o:rd}', ' ', - 'w', '{o:r}', 'd', ' ', '{w:or}', 'd', - ' ', 'w[]ord', ' ', '{posargs:{a key}}', - ] - - assert parsed == expected - - def test_command_with_runs_of_whitespace(self): - cmd = "cmd1 {item1}\n {item2}" - p = CommandParser(cmd) - parsed = list(p.words()) - assert parsed == ['cmd1', ' ', '{item1}', '\n ', '{item2}'] - - def test_command_with_split_line_in_subst_arguments(self): - cmd = dedent(""" cmd2 {posargs:{item2} - other}""") - p = CommandParser(cmd) - parsed = list(p.words()) - assert parsed == ['cmd2', ' ', '{posargs:{item2}\n other}'] - - def test_command_parsing_for_issue_10(self): - cmd = "nosetests -v -a !deferred --with-doctest []" - p = CommandParser(cmd) - parsed = list(p.words()) - assert parsed == [ - 'nosetests', ' ', '-v', ' ', '-a', ' ', '!deferred', ' ', - '--with-doctest', ' ', '[]' - ] - - @pytest.mark.skipif("sys.platform != 'win32'") - def test_commands_with_backslash(self, newconfig): - config = newconfig([r"hello\world"], """ - [testenv:py26] - commands = some {posargs} - """) - envconfig = config.envconfigs["py26"] - assert envconfig.commands[0] == ["some", r"hello\world"] |