Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some basic lint issues in vitess/py, add effective_caller_id to vtgate_cursor interfaces. #1026

Merged
merged 13 commits into from
Aug 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions py/cbson/setup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from distutils.core import setup, Extension
from distutils.core import Extension
from distutils.core import setup

cbson = Extension('cbson',
sources = ['cbson.c'])
sources=['cbson.c'])

setup(name = 'cbson',
version = '0.1',
description = 'Fast BSON decoding via C',
ext_modules = [cbson])
setup(name='cbson',
version='0.1',
description='Fast BSON decoding via C',
ext_modules=[cbson])
82 changes: 60 additions & 22 deletions py/cbson/test_cbson.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,54 @@
sys.path.append(os.path.split(os.path.abspath(__file__))[0])
import cbson


def test_load_empty():
"""
"""Doctest.

>>> cbson.loads('')
Traceback (most recent call last):
...
BSONError: empty buffer
"""


def test_load_binary():
r"""
r"""Doctest.

>>> s = cbson.dumps({'world': 'hello'})
>>> s
'\x16\x00\x00\x00\x05world\x00\x05\x00\x00\x00\x00hello\x00'
>>> cbson.loads(s)
{'world': 'hello'}
"""


def test_load_string():
r"""
r"""Doctest.

>>> s = cbson.dumps({'world': u'hello \u00fc'})
>>> s
'\x19\x00\x00\x00\x02world\x00\t\x00\x00\x00hello \xc3\xbc\x00\x00'
>>> cbson.loads(s)
{'world': u'hello \xfc'}
"""


def test_load_int():
r"""
r"""Doctest.

>>> s = cbson.dumps({'int': 1334})
>>> s
'\x0e\x00\x00\x00\x10int\x006\x05\x00\x00\x00'
>>> cbson.loads(s)
{'int': 1334}
"""


# the library doesn't allow creation of these, so just check the unpacking
def test_unpack_uint64():
r"""
r"""Doctest.

>>> s = '\x12\x00\x00\x00\x3fint\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'
>>> cbson.loads(s)
{'int': 1L}
Expand All @@ -58,83 +68,103 @@ def test_unpack_uint64():
{'int': 10376293541461622784L}
"""


def test_bool():
"""
"""Doctest.

>>> cbson.loads(cbson.dumps({'yes': True, 'no': False}))['yes']
True
>>> cbson.loads(cbson.dumps({'yes': True, 'no': False}))['no']
False
"""


def test_none():
r"""
r"""Doctest.

>>> s = cbson.dumps({'none': None})
>>> s
'\x0b\x00\x00\x00\nnone\x00\x00'
>>> cbson.loads(s)
{'none': None}
"""


def test_array():
r"""
r"""Doctest.

>>> s = cbson.dumps({'lst': [1, 2, 3, 4, 'hello', None]})
>>> s
';\x00\x00\x00\x04lst\x001\x00\x00\x00\x100\x00\x01\x00\x00\x00\x101\x00\x02\x00\x00\x00\x102\x00\x03\x00\x00\x00\x103\x00\x04\x00\x00\x00\x054\x00\x05\x00\x00\x00\x00hello\n5\x00\x00\x00'
>>> cbson.loads(s)
{'lst': [1, 2, 3, 4, 'hello', None]}
"""


def test_dict():
"""
"""Doctest.

>>> d = {'a': None, 'b': 2, 'c': 'hello', 'd': 1.02, 'e': ['a', 'b', 'c']}
>>> cbson.loads(cbson.dumps(d)) == d
True
"""


def test_nested_dict():
r"""
r"""Doctest.

>>> s = cbson.dumps({'a': {'b': {'c': 0}}})
>>> s
'\x1c\x00\x00\x00\x03a\x00\x14\x00\x00\x00\x03b\x00\x0c\x00\x00\x00\x10c\x00\x00\x00\x00\x00\x00\x00\x00'
>>> cbson.loads(s)
{'a': {'b': {'c': 0}}}
"""


def test_dict_in_array():
r"""
r"""Doctest.

>>> s = cbson.dumps({'a': [{'b': 0}, {'c': 1}]})
>>> s
'+\x00\x00\x00\x04a\x00#\x00\x00\x00\x030\x00\x0c\x00\x00\x00\x10b\x00\x00\x00\x00\x00\x00\x031\x00\x0c\x00\x00\x00\x10c\x00\x01\x00\x00\x00\x00\x00\x00'
>>> cbson.loads(s)
{'a': [{'b': 0}, {'c': 1}]}
"""


def test_eob1():
"""
"""Doctest.

>>> cbson.loads(BSON(BSON_TAG(1), NULL_BYTE))
Traceback (most recent call last):
...
BSONError: unexpected end of buffer: wanted 8 bytes at buffer[6] for double
"""


def test_eob2():
"""
"""Doctest.

>>> cbson.loads(BSON(BSON_TAG(2), NULL_BYTE))
Traceback (most recent call last):
...
BSONError: unexpected end of buffer: wanted 4 bytes at buffer[6] for string-length
"""


def test_eob_cstring():
"""
"""Doctest.

>>> cbson.loads(BSON(BSON_TAG(1)))
Traceback (most recent call last):
...
BSONError: unexpected end of buffer: non-terminated cstring at buffer[5] for element-name
"""


def test_decode_next():
"""
"""Doctest.

>>> s = cbson.dumps({'a': 1}) + cbson.dumps({'b': 2.0}) + cbson.dumps({'c': [None]})
>>> cbson.decode_next(s)
(12, {'a': 1})
Expand All @@ -144,8 +174,10 @@ def test_decode_next():
(44, {'c': [None]})
"""


def test_decode_next_eob():
"""
"""Doctest.

>>> s_full = cbson.dumps({'a': 1}) + cbson.dumps({'b': 2.0})
>>> s = s_full[:-1]
>>> cbson.decode_next(s)
Expand All @@ -164,8 +196,10 @@ def test_decode_next_eob():
BSONBufferTooShort: ('buffer too short: buffer[12:] does not contain 12 bytes for document', 2)
"""


def test_encode_recursive():
"""
"""Doctest.

>>> a = []
>>> a.append(a)
>>> cbson.dumps({"x": a})
Expand All @@ -174,8 +208,10 @@ def test_encode_recursive():
ValueError: object too deeply nested to BSON encode
"""


def test_encode_invalid():
"""
"""Doctest.

>>> cbson.dumps(object())
Traceback (most recent call last):
...
Expand All @@ -186,24 +222,26 @@ def test_encode_invalid():
TypeError: unsupported type for BSON encode
"""


def BSON(*l):
buf = ''.join(l)
return struct.pack('i', len(buf)+4) + buf


def BSON_TAG(type_id):
return struct.pack('b', type_id)

NULL_BYTE = '\x00'

if __name__ == "__main__":
if __name__ == '__main__':
cbson

import doctest
print "Running selftest:"
print 'Running selftest:'
status = doctest.testmod(sys.modules[__name__])
if status[0]:
print "*** %s tests of %d failed." % status
print '*** %s tests of %d failed.' % status
sys.exit(1)
else:
print "--- %s tests passed." % status[1]
print '--- %s tests passed.' % status[1]
sys.exit(0)
20 changes: 11 additions & 9 deletions py/cbson/test_cbson_bad_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@
# crash the decoder, before we fixed the issues.
# Only base64 encoded so they aren't a million characters long and/or full
# of escape sequences.
KNOWN_BAD = ["VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAAAQMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQwADAAAARFMAAB0A",
"VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAADTMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQwADAAAARFMAAAAA",
"VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAAAQMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQ2gDAAAARFMAAAAA",
]
KNOWN_BAD = [
"VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAAAQMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQwADAAAARFMAAB0A",
"VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAADTMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQwADAAAARFMAAAAA",
"VAAAAARBAEwAAAAQMAABAAAAEDEAAgAAABAyAAMAAAAQMwAEAAAAEDQABQAAAAU"
"1AAEAAAAANgI2AAIAAAA3AAM3AA8AAAACQ2gDAAAARFMAAAAA",
]


class CbsonTest(unittest.TestCase):

def test_short_string_segfaults(self):
a = cbson.dumps({"A": [1, 2, 3, 4, 5, "6", u"7", {"C": u"DS"}]})
for i in range(len(a))[1:]:
Expand All @@ -40,7 +43,7 @@ def test_known_bad(self):
def test_random_segfaults(self):
a = cbson.dumps({"A": [1, 2, 3, 4, 5, "6", u"7", {"C": u"DS"}]})
sys.stdout.write("\nQ: %s\n" % (binascii.hexlify(a),))
for i in range(1000):
for _ in range(1000):
l = [c for c in a]
l[random.randint(4, len(a)-1)] = chr(random.randint(0, 255))
try:
Expand All @@ -54,4 +57,3 @@ def test_random_segfaults(self):

if __name__ == "__main__":
unittest.main()

20 changes: 13 additions & 7 deletions py/net/bsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

# Go-style RPC client using BSON as the codec.

import bson
import hmac
import struct

import bson
try:
# use optimized cbson which has slightly different API
import cbson
Expand All @@ -25,19 +26,23 @@
unpack_length = len_struct.unpack_from
len_struct_size = len_struct.size


class BsonRpcClient(gorpc.GoRpcClient):

def __init__(self, addr, timeout, user=None, password=None,
keyfile=None, certfile=None):
if bool(user) != bool(password):
raise ValueError("You must provide either both or none of user and password.")
raise ValueError(
'You must provide either both or none of user and password.')
self.addr = addr
self.user = user
self.password = password
if self.user:
uri = 'http://%s/_bson_rpc_/auth' % self.addr
else:
uri = 'http://%s/_bson_rpc_' % self.addr
gorpc.GoRpcClient.__init__(self, uri, timeout, keyfile=keyfile, certfile=certfile)
gorpc.GoRpcClient.__init__(
self, uri, timeout, keyfile=keyfile, certfile=certfile)

def dial(self):
gorpc.GoRpcClient.dial(self)
Expand All @@ -49,10 +54,11 @@ def dial(self):
raise

def authenticate(self):
challenge = self.call('AuthenticatorCRAMMD5.GetNewChallenge', "").reply['Challenge']
challenge = self.call(
'AuthenticatorCRAMMD5.GetNewChallenge', '').reply['Challenge']
# CRAM-MD5 authentication.
proof = self.user + " " + hmac.HMAC(self.password, challenge).hexdigest()
self.call('AuthenticatorCRAMMD5.Authenticate', {"Proof": proof})
proof = self.user + ' ' + hmac.HMAC(self.password, challenge).hexdigest()
self.call('AuthenticatorCRAMMD5.Authenticate', {'Proof': proof})

def encode_request(self, req):
try:
Expand Down Expand Up @@ -81,7 +87,7 @@ def decode_response(self, response, data):
# decode the payload length and see if we have enough
body_len = unpack_length(data, header_len)[0]
if data_len < header_len + body_len:
return None, header_len + body_len - data_len
return None, header_len + body_len - data_len

# we have enough data, decode it all
try:
Expand Down
Loading