Skip to content

Commit c2bc068

Browse files
authored
Merge pull request #204 from man-group/bugfix/server-fixtures
Bugfix/server fixtures
2 parents e07b520 + 8cd63fa commit c2bc068

File tree

17 files changed

+194
-100
lines changed

17 files changed

+194
-100
lines changed

.circleci/config.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ test-tmpl: &test-tmpl
33
command: |
44
. ../venv/bin/activate
55
export DEBUG=1
6+
export SERVER_FIXTURES_HOSTNAME=127.0.0.1
67
export SERVER_FIXTURES_JENKINS_WAR=
78
cat *.egg-info/top_level.txt | xargs -Ipysrc coverage run -p --source=pysrc setup.py test -sv -ra || touch ../FAILED-$(basename $PWD)
89
@@ -132,11 +133,6 @@ job-tmpl: &job-tmpl
132133

133134
version: 2
134135
jobs:
135-
py35:
136-
<<: *job-tmpl
137-
environment:
138-
PYTHON: "python3.5"
139-
140136
py36:
141137
<<: *job-tmpl
142138
environment:

Makefile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ EXTRA_DEPS = setuptools-git \
88
python-jenkins \
99
redis \
1010
pymongo \
11-
psycopg2 \
11+
psycopg2-binary\
1212
boto3 \
1313
rethinkdb \
1414
docker \
@@ -17,18 +17,21 @@ EXTRA_DEPS = setuptools-git \
1717

1818
COPY_FILES = VERSION CHANGES.md common_setup.py MANIFEST.in LICENSE
1919
UPLOAD_OPTS =
20+
PYPI_INDEX =
21+
22+
PIP_INSTALL_ARGS := $(shell [ ! -z "${PYPI_INDEX}" ] && echo --index ${PYPI_INDEX} )
2023

2124
# removed from PHONY: circleci_sip circleci_pyqt
2225
.PHONY: extras copyfiles wheels eggs sdists install develop test upload clean
2326

2427
extras:
25-
pip install $(EXTRA_DEPS)
28+
pip install ${PIP_INSTALL_ARGS} ${EXTRA_DEPS}
2629

2730
copyfiles:
28-
./foreach.sh 'for file in $(COPY_FILES); do cp ../$$file .; done'
31+
./foreach.sh 'for file in ${COPY_FILES}; do cp ../$$file .; done'
2932

3033
wheels: copyfiles
31-
pip install -U wheel
34+
pip install ${PIP_INSTALL_ARGS} -U wheel
3235
./foreach.sh --changed 'python setup.py bdist_wheel'
3336

3437
eggs: copyfiles
@@ -38,12 +41,12 @@ sdists: copyfiles
3841
./foreach.sh --changed 'python setup.py sdist'
3942

4043
install: copyfiles
41-
pip install -U wheel
44+
pip install ${PIP_INSTALL_ARGS} -U wheel
4245
./foreach.sh 'python setup.py bdist_wheel'
43-
./foreach.sh 'pip install dist/*.whl'
46+
./foreach.sh 'pip install ${PIP_INSTALL_ARGS} dist/*.whl'
4447

4548
develop: copyfiles extras
46-
./foreach.sh 'pip install -e.[tests]'
49+
./foreach.sh 'pip install ${PIP_INSTALL_ARGS} -e.[tests]'
4750

4851
test:
4952
rm -f FAILED-*

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,21 @@ To run all the tests:
5151
make test
5252
```
5353

54-
To setup test environment in Vagrant (requires virtualbox):
54+
## Vagrant
55+
56+
Some of the plugins have complex dependencies, particularly `pytest-server-fixtures`.
57+
To make it easier to develop, there is a `Vagrantfile` which will setup a virtual machine
58+
with all the dependencies installed to run the tests.
59+
60+
To set up the environment in Vagrant (requires virtualbox) and run the tests:
5561

5662
```bash
5763
$ vagrant up
5864
$ vagrant ssh
5965

6066
# ..... inside vagrant ....
6167
. venv/bin/activate
68+
cd src
6269
make develop
6370
make test
6471
```
@@ -72,3 +79,20 @@ This example will build all the wheel distributions:
7279
./foreach.sh python setup.py bdist_wheel
7380
```
7481

82+
### Only-Changed mode
83+
84+
To run a command only on packages that have changed since the last tagged release, use `--changed`.
85+
This example will only upload packages that need releasing:
86+
87+
```bash
88+
./foreach.sh python setup.py bdist_wheel upload
89+
```
90+
91+
### Quiet mode
92+
93+
To run a command with no extra output other than from what you run, use `--quiet`
94+
```bash
95+
./foreach.sh --quiet grep PY3
96+
```
97+
98+

install.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@ function install_python_packaging {
3232
function install_python {
3333
local py=$1
3434
apt-get install -y $py $py-dev
35-
curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | $py
35+
if [ "$py" = "python3.6" ]; then
36+
curl --silent --show-error --retry 5 https://bootstrap.pypa.io/pip/3.6/get-pip.py | $py
37+
else
38+
curl --silent --show-error --retry 5 https://bootstrap.pypa.io/get-pip.py | $py
39+
fi
3640
install_python_packaging $py
3741
}
3842

39-
4043
function choco_install {
4144
local args=$*
4245
# choco fails randomly with network errors on travis, have a few goes
@@ -115,7 +118,8 @@ function install_system_deps {
115118
x11-utils \
116119
subversion \
117120
graphviz \
118-
pandoc
121+
pandoc \
122+
net-tools
119123
}
120124

121125
function install_postgresql {

pytest-profiling/pytest_profiling.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pstats
99
import errno
1010
from hashlib import md5
11-
from subprocess import Popen, PIPE
11+
import subprocess
1212

1313
import six
1414
import pytest
@@ -71,8 +71,8 @@ def pytest_sessionfinish(self, session, exitstatus): # @UnusedVariable
7171

7272
# A handcrafted Popen pipe actually seems to work on both windows and unix:
7373
# do it in 2 subprocesses, with a pipe in between
74-
pdot = Popen(dot_args, stdin=PIPE, shell=True)
75-
pgprof = Popen(gprof2dot_args, stdout=pdot.stdin, shell=True)
74+
pdot = subprocess.Popen(dot_args, stdin=subprocess.PIPE, shell=True)
75+
pgprof = subprocess.Popen(gprof2dot_args, stdout=pdot.stdin, shell=True)
7676
(stdoutdata1, stderrdata1) = pgprof.communicate()
7777
(stdoutdata2, stderrdata2) = pdot.communicate()
7878
if stderrdata1 is not None or pgprof.poll() > 0:

pytest-profiling/tests/unit/test_profile.py

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,31 @@
55
from six.moves import reload_module # @UnresolvedImport
66

77
import pytest_profiling
8+
89
reload_module(pytest_profiling)
910

11+
import os
12+
import subprocess
13+
1014
from pytest_profiling import Profiling, pytest_addoption, pytest_configure
1115

1216
try:
13-
from unittest.mock import Mock, ANY, patch, sentinel
17+
from unittest.mock import Mock, ANY, patch, sentinel, call
1418
except ImportError:
1519
# python 2
1620
from mock import Mock, ANY, patch, sentinel
1721

1822

1923
def test_creates_prof_dir():
20-
with patch('os.makedirs', side_effect=OSError) as makedirs:
24+
with patch("os.makedirs", side_effect=OSError) as makedirs:
2125
Profiling(False).pytest_sessionstart(Mock())
22-
makedirs.assert_called_with('prof')
26+
makedirs.assert_called_with("prof")
2327

2428

2529
def test_combines_profs():
2630
plugin = Profiling(False)
2731
plugin.profs = [sentinel.prof0, sentinel.prof1]
28-
with patch('pstats.Stats') as Stats:
32+
with patch("pstats.Stats") as Stats:
2933
plugin.pytest_sessionfinish(Mock(), Mock())
3034
Stats.assert_called_once_with(sentinel.prof0)
3135
Stats.return_value.add.assert_called_once_with(sentinel.prof1)
@@ -34,51 +38,73 @@ def test_combines_profs():
3438

3539
def test_generates_svg():
3640
plugin = Profiling(True)
41+
plugin.gprof2dot = "/somewhere/gprof2dot"
3742
plugin.profs = [sentinel.prof]
38-
with patch('pstats.Stats'):
39-
with patch('pipes.Template') as Template:
43+
popen1 = Mock(
44+
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
45+
)
46+
popen2 = Mock(
47+
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
48+
)
49+
with patch("pstats.Stats"):
50+
with patch("subprocess.Popen", side_effect=[popen1, popen2]) as popen:
4051
plugin.pytest_sessionfinish(Mock(), Mock())
41-
assert any('gprof2dot' in args[0][0] for args in Template.return_value.append.call_args_list)
42-
assert Template.return_value.copy.called
52+
calls = popen.mock_calls
53+
assert calls[0] == call(
54+
["dot", "-Tsvg", "-o", f"{os.getcwd()}/prof/combined.svg"],
55+
stdin=subprocess.PIPE,
56+
shell=True,
57+
)
58+
assert calls[1] == call(
59+
["/somewhere/gprof2dot", "-f", "pstats", f"{os.getcwd()}/prof/combined.prof"],
60+
stdout=popen1.stdin,
61+
shell=True,
62+
)
4363

4464

4565
def test_writes_summary():
4666
plugin = Profiling(False)
4767
plugin.profs = [sentinel.prof]
4868
terminalreporter, stats = Mock(), Mock()
49-
with patch('pstats.Stats', return_value=stats) as Stats:
69+
with patch("pstats.Stats", return_value=stats) as Stats:
5070
plugin.pytest_sessionfinish(Mock(), Mock())
5171
plugin.pytest_terminal_summary(terminalreporter)
52-
assert 'Profiling' in terminalreporter.write.call_args[0][0]
72+
assert "Profiling" in terminalreporter.write.call_args[0][0]
5373
assert Stats.called_with(stats, stream=terminalreporter)
5474

5575

5676
def test_writes_summary_svg():
5777
plugin = Profiling(True)
5878
plugin.profs = [sentinel.prof]
5979
terminalreporter = Mock()
60-
with patch('pstats.Stats'):
61-
with patch('pipes.Template'):
80+
popen1 = Mock(
81+
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
82+
)
83+
popen2 = Mock(
84+
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
85+
)
86+
with patch("pstats.Stats"):
87+
with patch("subprocess.Popen", side_effect=[popen1, popen2]):
6288
plugin.pytest_sessionfinish(Mock(), Mock())
6389
plugin.pytest_terminal_summary(terminalreporter)
64-
assert 'SVG' in terminalreporter.write.call_args[0][0]
90+
assert "SVG" in terminalreporter.write.call_args[0][0]
6591

6692

6793
def test_adds_options():
6894
parser = Mock()
6995
pytest_addoption(parser)
70-
parser.getgroup.assert_called_with('Profiling')
96+
parser.getgroup.assert_called_with("Profiling")
7197
group = parser.getgroup.return_value
72-
group.addoption.assert_any_call('--profile', action='store_true', help=ANY)
73-
group.addoption.assert_any_call('--profile-svg', action='store_true', help=ANY)
98+
group.addoption.assert_any_call("--profile", action="store_true", help=ANY)
99+
group.addoption.assert_any_call("--profile-svg", action="store_true", help=ANY)
74100

75101

76102
def test_configures():
77-
config = Mock(getvalue=lambda x: x == 'profile')
78-
with patch('pytest_profiling.Profiling') as Profiling:
103+
config = Mock(getvalue=lambda x: x == "profile")
104+
with patch("pytest_profiling.Profiling") as Profiling:
79105
pytest_configure(config)
80106
config.pluginmanager.register.assert_called_with(Profiling.return_value)
81107

82108

83109
def test_clean_filename():
84-
assert pytest_profiling.clean_filename('a:b/c\256d') == 'a_b_c_d'
110+
assert pytest_profiling.clean_filename("a:b/c\256d") == "a_b_c_d"

pytest-pyramid-server/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ To do this you can use the underlying server class directly - this is an implene
7676
'my_dbpass: 'bar'}}
7777
) as server:
7878
assert not server.dead
79-
assert 'my_dbname = foo' in server.working_config.text()
79+
assert 'my_dbname = foo' in server.working_config.read_text()
8080

8181
# Server should now be dead
8282
assert server.dead

pytest-pyramid-server/pytest_pyramid_server.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from paste.deploy.loadwsgi import loadapp
2121
from pytest import yield_fixture
2222

23+
from pytest_server_fixtures import CONFIG
2324
from pytest_server_fixtures.http import HTTPTestServer
2425

2526

@@ -83,8 +84,7 @@ def __init__(self, config_dir=None, config_filename=None, extra_config_vars=None
8384
# Always print debug output for this process
8485
os.environ['DEBUG'] = '1'
8586

86-
# Discover externally accessable hostname so selenium can get to it
87-
kwargs['hostname'] = kwargs.get('hostname', socket.gethostbyname(os.uname()[1]))
87+
kwargs['hostname'] = kwargs.get('hostname', CONFIG.fixture_hostname)
8888

8989
super(PyramidTestServer, self).__init__(preserve_sys_path=True, **kwargs)
9090

@@ -112,8 +112,8 @@ def pre_setup(self):
112112
except configparser.NoOptionError:
113113
parser.set('app:main', 'url_prefix', '')
114114

115-
# Set the uri to be the external hostname and the url prefix
116-
self._uri = "http://%s:%s/%s" % (os.uname()[1], self.port, parser.get('app:main', 'url_prefix'))
115+
# Set the uri to be the hostname and the url prefix
116+
self._uri = "http://%s:%s/%s" % (self.hostname, self.port, parser.get('app:main', 'url_prefix'))
117117

118118
@property
119119
def run_cmd(self):

0 commit comments

Comments
 (0)