File: //kunden/proc/self/root/lib/python3/dist-packages/breezy/plugins/launchpad/test_register.py
# Copyright (C) 2006-2012, 2016-2017 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from io import BytesIO
try:
from xmlrpc.client import (
loads as xmlrpc_loads,
Transport,
)
except ImportError: # python < 3
from xmlrpclib import (
loads as xmlrpc_loads,
Transport,
)
from ...sixish import PY3
from ...tests import TestCaseWithTransport
# local import
from .lp_registration import (
BaseRequest,
ResolveLaunchpadPathRequest,
LaunchpadService,
)
# TODO: Test that the command-line client, making sure that it'll pass the
# request through to a dummy transport, and that the transport will validate
# the results passed in. Not sure how to get the transport object back out to
# validate that its OK - may not be necessary.
class InstrumentedXMLRPCConnection(object):
"""Stands in place of an http connection for the purposes of testing"""
def __init__(self, testcase):
self.testcase = testcase
def getreply(self):
"""Fake the http reply.
:returns: (errcode, errmsg, headers)
"""
return (200, 'OK', [])
def getresponse(self, buffering=True):
"""Fake the http reply.
This is used when running on Python 2.7, where xmlrpclib uses
httplib.HTTPConnection in a different way than before.
"""
class FakeHttpResponse(object):
def __init__(self, status, reason, body):
self.status = status
self.reason = reason
self.body = body
def read(self, size=-1):
return self.body.read(size)
def getheader(self, name, default):
# We don't have headers
return default
return FakeHttpResponse(200, 'OK', self.getfile())
def getfile(self):
"""Return a fake file containing the response content."""
return BytesIO(b'''\
<?xml version="1.0" ?>
<methodResponse>
<params>
<param>
<value>
<string>victoria dock</string>
</value>
</param>
</params>
</methodResponse>''')
class InstrumentedXMLRPCTransport(Transport):
# Python 2.5's xmlrpclib looks for this.
_use_datetime = False
_use_builtin_types = False
def __init__(self, testcase):
self.testcase = testcase
self._connection = (None, None)
def make_connection(self, host):
host, http_headers, x509 = self.get_host_info(host)
test = self.testcase
self.connected_host = host
if http_headers:
raise AssertionError()
return InstrumentedXMLRPCConnection(test)
if PY3:
def send_request(self, host, handler_path, request_body,
verbose=None):
self.connected_host = host
test = self.testcase
self.got_request = True
unpacked, method = xmlrpc_loads(request_body)
if None in unpacked:
raise AssertionError(
"xmlrpc result %r shouldn't contain None" % (unpacked,))
self.sent_params = unpacked
return InstrumentedXMLRPCConnection(test)
else:
def send_request(self, connection, handler_path, request_body,
verbose=None):
test = self.testcase
self.got_request = True
def send_host(self, conn, host):
pass
def send_user_agent(self, conn):
# TODO: send special user agent string, including breezy version
# number
pass
def send_content(self, conn, request_body):
unpacked, method = xmlrpc_loads(request_body)
if None in unpacked:
raise AssertionError(
"xmlrpc result %r shouldn't contain None" % (unpacked,))
self.sent_params = unpacked
class MockLaunchpadService(LaunchpadService):
def send_request(self, method_name, method_params, verbose=None):
"""Stash away the method details rather than sending them to a real server"""
self.called_method_name = method_name
self.called_method_params = method_params
class TestResolveLaunchpadPathRequest(TestCaseWithTransport):
def setUp(self):
super(TestResolveLaunchpadPathRequest, self).setUp()
# make sure we have a reproducible standard environment
self.overrideEnv('BRZ_LP_XMLRPC_URL', None)
def test_onto_transport(self):
"""A request is transmitted across a mock Transport"""
transport = InstrumentedXMLRPCTransport(self)
service = LaunchpadService(transport)
resolve = ResolveLaunchpadPathRequest('bzr')
resolve.submit(service)
self.assertEqual(transport.connected_host, 'xmlrpc.launchpad.net')
self.assertEqual(len(transport.sent_params), 1)
self.assertEqual(transport.sent_params, ('bzr', ))
self.assertTrue(transport.got_request)
def test_subclass_request(self):
"""Define a new type of xmlrpc request"""
class DummyRequest(BaseRequest):
_methodname = 'dummy_request'
def _request_params(self):
return (42,)
service = MockLaunchpadService()
service.registrant_email = 'test@launchpad.net'
service.registrant_password = ''
request = DummyRequest()
request.submit(service)
self.assertEqual(service.called_method_name, 'dummy_request')
self.assertEqual(service.called_method_params, (42,))
def test_mock_resolve_lp_url(self):
test_case = self
class MockService(MockLaunchpadService):
def send_request(self, method_name, method_params,
verbose=None):
test_case.assertEqual(method_name, "resolve_lp_path")
test_case.assertEqual(list(method_params), ['bzr'])
return dict(urls=[
'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
'http://bazaar.launchpad.net~bzr/bzr/trunk'])
service = MockService()
resolve = ResolveLaunchpadPathRequest('bzr')
result = resolve.submit(service)
self.assertTrue('urls' in result)
self.assertEqual(result['urls'], [
'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
'http://bazaar.launchpad.net~bzr/bzr/trunk'])