Skip to content

Commit

Permalink
Fixed server and profiling unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
eeaston committed Apr 22, 2022
1 parent 68d4f7c commit 8cd63fa
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 30 deletions.
6 changes: 3 additions & 3 deletions pytest-profiling/pytest_profiling.py
Expand Up @@ -8,7 +8,7 @@
import pstats
import errno
from hashlib import md5
from subprocess import Popen, PIPE
import subprocess

import six
import pytest
Expand Down Expand Up @@ -71,8 +71,8 @@ def pytest_sessionfinish(self, session, exitstatus): # @UnusedVariable

# A handcrafted Popen pipe actually seems to work on both windows and unix:
# do it in 2 subprocesses, with a pipe in between
pdot = Popen(dot_args, stdin=PIPE, shell=True)
pgprof = Popen(gprof2dot_args, stdout=pdot.stdin, shell=True)
pdot = subprocess.Popen(dot_args, stdin=subprocess.PIPE, shell=True)
pgprof = subprocess.Popen(gprof2dot_args, stdout=pdot.stdin, shell=True)
(stdoutdata1, stderrdata1) = pgprof.communicate()
(stdoutdata2, stderrdata2) = pdot.communicate()
if stderrdata1 is not None or pgprof.poll() > 0:
Expand Down
64 changes: 45 additions & 19 deletions pytest-profiling/tests/unit/test_profile.py
Expand Up @@ -5,27 +5,31 @@
from six.moves import reload_module # @UnresolvedImport

import pytest_profiling

reload_module(pytest_profiling)

import os
import subprocess

from pytest_profiling import Profiling, pytest_addoption, pytest_configure

try:
from unittest.mock import Mock, ANY, patch, sentinel
from unittest.mock import Mock, ANY, patch, sentinel, call
except ImportError:
# python 2
from mock import Mock, ANY, patch, sentinel


def test_creates_prof_dir():
with patch('os.makedirs', side_effect=OSError) as makedirs:
with patch("os.makedirs", side_effect=OSError) as makedirs:
Profiling(False).pytest_sessionstart(Mock())
makedirs.assert_called_with('prof')
makedirs.assert_called_with("prof")


def test_combines_profs():
plugin = Profiling(False)
plugin.profs = [sentinel.prof0, sentinel.prof1]
with patch('pstats.Stats') as Stats:
with patch("pstats.Stats") as Stats:
plugin.pytest_sessionfinish(Mock(), Mock())
Stats.assert_called_once_with(sentinel.prof0)
Stats.return_value.add.assert_called_once_with(sentinel.prof1)
Expand All @@ -34,51 +38,73 @@ def test_combines_profs():

def test_generates_svg():
plugin = Profiling(True)
plugin.gprof2dot = "/somewhere/gprof2dot"
plugin.profs = [sentinel.prof]
with patch('pstats.Stats'):
with patch('pipes.Template') as Template:
popen1 = Mock(
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
)
popen2 = Mock(
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
)
with patch("pstats.Stats"):
with patch("subprocess.Popen", side_effect=[popen1, popen2]) as popen:
plugin.pytest_sessionfinish(Mock(), Mock())
assert any('gprof2dot' in args[0][0] for args in Template.return_value.append.call_args_list)
assert Template.return_value.copy.called
calls = popen.mock_calls
assert calls[0] == call(
["dot", "-Tsvg", "-o", f"{os.getcwd()}/prof/combined.svg"],
stdin=subprocess.PIPE,
shell=True,
)
assert calls[1] == call(
["/somewhere/gprof2dot", "-f", "pstats", f"{os.getcwd()}/prof/combined.prof"],
stdout=popen1.stdin,
shell=True,
)


def test_writes_summary():
plugin = Profiling(False)
plugin.profs = [sentinel.prof]
terminalreporter, stats = Mock(), Mock()
with patch('pstats.Stats', return_value=stats) as Stats:
with patch("pstats.Stats", return_value=stats) as Stats:
plugin.pytest_sessionfinish(Mock(), Mock())
plugin.pytest_terminal_summary(terminalreporter)
assert 'Profiling' in terminalreporter.write.call_args[0][0]
assert "Profiling" in terminalreporter.write.call_args[0][0]
assert Stats.called_with(stats, stream=terminalreporter)


def test_writes_summary_svg():
plugin = Profiling(True)
plugin.profs = [sentinel.prof]
terminalreporter = Mock()
with patch('pstats.Stats'):
with patch('pipes.Template'):
popen1 = Mock(
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
)
popen2 = Mock(
communicate=Mock(return_value=[None, None]), poll=Mock(return_value=0)
)
with patch("pstats.Stats"):
with patch("subprocess.Popen", side_effect=[popen1, popen2]):
plugin.pytest_sessionfinish(Mock(), Mock())
plugin.pytest_terminal_summary(terminalreporter)
assert 'SVG' in terminalreporter.write.call_args[0][0]
assert "SVG" in terminalreporter.write.call_args[0][0]


def test_adds_options():
parser = Mock()
pytest_addoption(parser)
parser.getgroup.assert_called_with('Profiling')
parser.getgroup.assert_called_with("Profiling")
group = parser.getgroup.return_value
group.addoption.assert_any_call('--profile', action='store_true', help=ANY)
group.addoption.assert_any_call('--profile-svg', action='store_true', help=ANY)
group.addoption.assert_any_call("--profile", action="store_true", help=ANY)
group.addoption.assert_any_call("--profile-svg", action="store_true", help=ANY)


def test_configures():
config = Mock(getvalue=lambda x: x == 'profile')
with patch('pytest_profiling.Profiling') as Profiling:
config = Mock(getvalue=lambda x: x == "profile")
with patch("pytest_profiling.Profiling") as Profiling:
pytest_configure(config)
config.pluginmanager.register.assert_called_with(Profiling.return_value)


def test_clean_filename():
assert pytest_profiling.clean_filename('a:b/c\256d') == 'a_b_c_d'
assert pytest_profiling.clean_filename("a:b/c\256d") == "a_b_c_d"
16 changes: 8 additions & 8 deletions pytest-server-fixtures/tests/unit/test_server_unit.py
Expand Up @@ -22,15 +22,15 @@ def test_init():
ts.workspace = ws


def test_kill():
self = create_autospec(_TestServer, dead=False,
hostname=sentinel.hostname,
port=sentinel.port)
self.run.side_effect = ['100\n', '', '']
def test_kill_by_port():
server = _TestServer(hostname=sentinel.hostname, port=sentinel.port)
server.run = Mock(side_effect=['100\n', '', ''])
server._signal = Mock()
with patch('socket.gethostbyname', return_value=sentinel.ip):
_TestServer._find_and_kill_by_port(self, 2, sentinel.signal)
assert self.run.call_args_list == [call("netstat -anp 2>/dev/null | grep sentinel.ip:sentinel.port "
server._find_and_kill_by_port(2, sentinel.signal)
server.dead = True
assert server.run.call_args_list == [call("netstat -anp 2>/dev/null | grep sentinel.ip:sentinel.port "
"| grep LISTEN | awk '{ print $7 }' | cut -d'/' -f1", capture=True, cd='/'),
call("netstat -anp 2>/dev/null | grep sentinel.ip:sentinel.port "
"| grep LISTEN | awk '{ print $7 }' | cut -d'/' -f1", capture=True, cd='/')]
assert self._signal.call_args_list == [call(100, sentinel.signal)]
assert server._signal.call_args_list == [call(100, sentinel.signal)]

0 comments on commit 8cd63fa

Please sign in to comment.