Fixing --pastebin option by using a POST request instead of a XMLRPC call

fixes #614

--HG--
branch : fix-pastebin
This commit is contained in:
Bruno Oliveira 2014-10-22 21:52:40 -02:00
parent 8480111012
commit 537dca477b
3 changed files with 82 additions and 35 deletions

View File

@ -19,6 +19,9 @@
- "python_classes" and "python_functions" options now support glob-patterns
for test discovery, as discussed in issue600. Thanks Ldiary Translations.
- fix issue614: fixed pastebin support.
2.6.4.dev
----------

View File

@ -3,10 +3,6 @@ import pytest
import py, sys
import tempfile
class url:
base = "http://bpaste.net"
xmlrpc = base + "/xmlrpc/"
show = base + "/show/"
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
@ -28,22 +24,45 @@ def pytest_configure(config):
def pytest_unconfigure(config):
if hasattr(config, '_pastebinfile'):
# get terminal contents and delete file
config._pastebinfile.seek(0)
sessionlog = config._pastebinfile.read()
config._pastebinfile.close()
del config._pastebinfile
proxyid = getproxy().newPaste("python", sessionlog)
pastebinurl = "%s%s" % (url.show, proxyid)
sys.stderr.write("pastebin session-log: %s\n" % pastebinurl)
# undo our patching in the terminal reporter
tr = config.pluginmanager.getplugin('terminalreporter')
del tr._tw.__dict__['write']
# write summary
tr.write_sep("=", "Sending information to Paste Service")
pastebinurl = create_new_paste(sessionlog)
tr.write_line("pastebin session-log: %s\n" % pastebinurl)
def getproxy():
def create_new_paste(contents):
"""
Creates a new paste using bpaste.net service.
:contents: paste contents
:returns: url to the pasted contents
"""
import re
if sys.version_info < (3, 0):
from xmlrpclib import ServerProxy
from urllib import urlopen, urlencode
else:
from xmlrpc.client import ServerProxy
return ServerProxy(url.xmlrpc).pastes
from urllib.request import urlopen
from urllib.parse import urlencode
params = {
'code': contents,
'lexer': 'python3' if sys.version_info[0] == 3 else 'python',
'expiry': '1week',
}
url = 'https://bpaste.net'
response = urlopen(url, data=urlencode(params)).read()
m = re.search(r'href="/raw/(\w+)"', response)
if m:
return '%s/show/%s' % (url, m.group(1))
else:
return 'bad response: ' + response
def pytest_terminal_summary(terminalreporter):
if terminalreporter.config.option.pastebin != "failed":
@ -51,9 +70,6 @@ def pytest_terminal_summary(terminalreporter):
tr = terminalreporter
if 'failed' in tr.stats:
terminalreporter.write_sep("=", "Sending information to Paste Service")
if tr.config.option.debug:
terminalreporter.write_line("xmlrpcurl: %s" %(url.xmlrpc,))
serverproxy = getproxy()
for rep in terminalreporter.stats.get('failed'):
try:
msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc
@ -63,6 +79,5 @@ def pytest_terminal_summary(terminalreporter):
rep.toterminal(tw)
s = tw.stringio.getvalue()
assert len(s)
proxyid = serverproxy.newPaste("python", s)
pastebinurl = "%s%s" % (url.show, proxyid)
pastebinurl = create_new_paste(s)
tr.write_line("%s --> %s" %(msg, pastebinurl))

View File

@ -1,13 +1,13 @@
import sys
import pytest
class TestPasting:
def pytest_funcarg__pastebinlist(self, request):
mp = request.getfuncargvalue("monkeypatch")
@pytest.fixture
def pastebinlist(self, monkeypatch, request):
pastebinlist = []
class MockProxy:
def newPaste(self, language, code):
pastebinlist.append((language, code))
plugin = request.config.pluginmanager.getplugin('pastebin')
mp.setattr(plugin, 'getproxy', MockProxy)
monkeypatch.setattr(plugin, 'create_new_paste', pastebinlist.append)
return pastebinlist
def test_failed(self, testdir, pastebinlist):
@ -22,8 +22,7 @@ class TestPasting:
""")
reprec = testdir.inline_run(testpath, "--paste=failed")
assert len(pastebinlist) == 1
assert pastebinlist[0][0] == "python"
s = pastebinlist[0][1]
s = pastebinlist[0]
assert s.find("def test_fail") != -1
assert reprec.countoutcomes() == [1,1,1]
@ -37,22 +36,52 @@ class TestPasting:
def test_skip():
pytest.skip("")
""")
reprec = testdir.inline_run(testpath, "--pastebin=all")
reprec = testdir.inline_run(testpath, "--pastebin=all", '-v')
assert reprec.countoutcomes() == [1,1,1]
assert len(pastebinlist) == 1
assert pastebinlist[0][0] == "python"
s = pastebinlist[0][1]
for x in 'test_fail test_skip skipped'.split():
assert s.find(x), (s, x)
s = pastebinlist[0]
for x in 'test_fail test_skip test_pass'.split():
assert x in s
class TestRPCClient:
def pytest_funcarg__pastebin(self, request):
class TestPaste:
@pytest.fixture
def pastebin(self, request):
return request.config.pluginmanager.getplugin('pastebin')
def test_getproxy(self, pastebin):
proxy = pastebin.getproxy()
assert proxy is not None
assert proxy.__class__.__module__.startswith('xmlrpc')
@pytest.fixture
def mocked_urlopen(self, monkeypatch):
"""
monkeypatch the actual urlopen calls done by the internal plugin
function that connects to bpaste service.
"""
calls = []
def mocked(url, data):
calls.append((url, data))
class DummyFile:
def read(self):
# part of html of a normal response
return 'View <a href="/raw/3c0c6750bd">raw</a>.'
return DummyFile()
if sys.version_info < (3, 0):
import urllib
monkeypatch.setattr(urllib, 'urlopen', mocked)
else:
import urllib.request
monkeypatch.setattr(urllib.request, 'urlopen', mocked)
return calls
def test_create_new_paste(self, pastebin, mocked_urlopen):
result = pastebin.create_new_paste('full-paste-contents')
assert result == 'https://bpaste.net/show/3c0c6750bd'
assert len(mocked_urlopen) == 1
url, data = mocked_urlopen[0]
lexer = 'python3' if sys.version_info[0] == 3 else 'python'
assert url == 'https://bpaste.net'
assert 'lexer=%s' % lexer in data
assert 'code=full-paste-contents' in data
assert 'expiry=1week' in data