Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #196 from uber/bryce_vcrw
Browse files Browse the repository at this point in the history
use thriftrw with vcr
  • Loading branch information
blampe committed Oct 12, 2015
2 parents 33ff89d + 8055c56 commit 1bf13c7
Show file tree
Hide file tree
Showing 15 changed files with 110 additions and 688 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Changes by Version
0.17.4 (unreleased)
-------------------

- Nothing changed yet.
- Updated ``vcr`` to use ``thriftrw``-generated code. This should resolve some
unicode errors during testing with ``vcr``.


0.17.3 (2015-10-09)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
'crcmod',
'tornado>=4.0,<5.0',
'toro>=0.8,<0.9',
'thriftrw>=0.3,<0.5',
'thriftrw>=0.4,<0.5',
'threadloop>=0.5,<0.6',
'futures',
],
Expand Down
2 changes: 1 addition & 1 deletion tchannel/testing/vcr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@
from .record_modes import RecordMode


__all__ = ['use_cassette', 'RecordMode']
__all__ = ['use_cassette', 'RecordMode', 'proxy']
8 changes: 3 additions & 5 deletions tchannel/testing/vcr/cassette.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
from .exceptions import RequestNotFoundError
from .exceptions import UnsupportedVersionError
from .record_modes import RecordMode
from .proxy.ttypes import Request
from .proxy.ttypes import Response

from . import proxy

__all__ = ['Cassette']

Expand All @@ -51,8 +49,8 @@ def to_primitive(self):
@classmethod
def to_native(cls, data):
return cls(
request=Request.to_native(data['request']),
response=Response.to_native(data['response']),
request=proxy.Request.from_primitive(data['request']),
response=proxy.Response.from_primitive(data['response']),
)


Expand Down
19 changes: 7 additions & 12 deletions tchannel/testing/vcr/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@
import wrapt
import sys

from tchannel.tornado import TChannel
from tchannel.thrift import client_for

from .cassette import Cassette
from .patch import Patcher, force_reset
from .server import VCRProxyService, VCRProxy


VCRProxyClient = client_for('vcr', VCRProxy)
from .proxy import VCRProxy
from .server import VCRProxyService


class _CassetteContext(object):
Expand All @@ -57,11 +52,11 @@ def __enter__(self):

# TODO Maybe instead of using this instance of the TChannel client, we
# should use the one being patched to make the requests?
client = VCRProxyClient(
tchannel=TChannel('proxy-client'),
hostport=server.hostport,
)
self._exit_stack.enter_context(Patcher(client))

# Need a better way to set hostport after loading!!
VCRProxy._module.hostport = server.hostport

self._exit_stack.enter_context(Patcher(VCRProxy))

return cassette

Expand Down
28 changes: 18 additions & 10 deletions tchannel/testing/vcr/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from tchannel.tornado.stream import maybe_stream
from tchannel.tornado.stream import read_full

from .proxy import VCRProxy
from . import proxy


_TChannel_request = TChannel.request
Expand Down Expand Up @@ -62,7 +62,7 @@ def __init__(
score_threshold=None,
):
self.vcr_client = vcr_client
self.hostport = hostport
self.hostport = hostport or ''
self.service = service or ''
self.arg_scheme = arg_scheme or schemes.DEFAULT
self.original_tchannel = original_tchannel
Expand All @@ -82,40 +82,48 @@ def send(self, arg1, arg2, arg3,
headers = headers or {}
headers.setdefault('as', self.arg_scheme)

vcr_request = VCRProxy.Request(
vcr_request = proxy.Request(
serviceName=self.service.encode('utf-8'),
hostPort=self.hostport,
knownPeers=self.original_tchannel.peers.hosts,
endpoint=endpoint,
headers=(yield read_full(arg2)),
body=(yield read_full(arg3)),
argScheme=getattr(VCRProxy.ArgScheme, self.arg_scheme.upper()),
argScheme=getattr(proxy.ArgScheme, self.arg_scheme.upper()),
transportHeaders=[
VCRProxy.TransportHeader(k, v) for k, v in headers.items()
proxy.TransportHeader(bytes(k), bytes(v))
for k, v in headers.items()
],
)

# TODO what to do with traceflag, attempt-times, ttl
# TODO catch protocol errors

from tchannel import TChannel
tchannel = TChannel('proxy-client')

thrift_request = self.vcr_client.send(vcr_request)

with force_reset():
vcr_response_future = self.vcr_client.send(vcr_request)
vcr_response_future = tchannel.thrift(thrift_request)

try:
vcr_response = yield vcr_response_future
except VCRProxy.RemoteServiceError as e:
except proxy.RemoteServiceError as e:
raise TChannelError.from_code(
e.code,
description=(
"The remote service threw a protocol error: %s" %
e.message
)
)

response = Response(
code=vcr_response.code,
code=vcr_response.body.code,
argstreams=[
maybe_stream(endpoint),
maybe_stream(vcr_response.headers),
maybe_stream(vcr_response.body),
maybe_stream(vcr_response.body.headers),
maybe_stream(vcr_response.body.body),
],
# TODO headers=vcr_response.transportHeaders,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,16 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

__all__ = ['ttypes', 'constants', 'VCRProxy']
import os
import sys

from tchannel import thrift

base = os.path.dirname(__file__)

proxy = thrift.load(
path=os.path.join(base, 'proxy.thrift'),
service='proxy-server',
)

sys.modules[__name__] = proxy
6 changes: 3 additions & 3 deletions tchannel/testing/vcr/proxy.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ enum ArgScheme {
}

struct TransportHeader {
1: binary key
2: binary value
1: required binary key
2: required binary value
}

struct Request {
Expand All @@ -29,7 +29,7 @@ struct Request {
*/
5: optional binary hostPort = ""
6: optional ArgScheme argScheme = ArgScheme.RAW
7: optional list<TransportHeader> transportHeaders = {}
7: optional list<TransportHeader> transportHeaders = []

/**
* List of known peers of the TChannel at the time the request was made.
Expand Down
Loading

0 comments on commit 1bf13c7

Please sign in to comment.