82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
|
# Copyright 2017 Google Inc.
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
|
||
|
import random
|
||
|
import string
|
||
|
import unittest
|
||
|
from unittest import mock
|
||
|
|
||
|
|
||
|
class JsonRpcClientTestBase(unittest.TestCase):
|
||
|
"""Base class for tests of JSONRPC clients.
|
||
|
|
||
|
Contains infrastructure for mocking responses.
|
||
|
"""
|
||
|
|
||
|
MOCK_RESP = (
|
||
|
b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1, '
|
||
|
b'"callback": null}')
|
||
|
MOCK_RESP_WITHOUT_CALLBACK = (
|
||
|
b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1}')
|
||
|
MOCK_RESP_TEMPLATE = (
|
||
|
'{"id": %d, "result": 123, "error": null, "status": 1, "uid": 1, '
|
||
|
'"callback": null}')
|
||
|
MOCK_RESP_UNKNOWN_STATUS = (
|
||
|
b'{"id": 0, "result": 123, "error": null, "status": 0, '
|
||
|
b'"callback": null}')
|
||
|
MOCK_RESP_WITH_CALLBACK = (
|
||
|
b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1, '
|
||
|
b'"callback": "1-0"}')
|
||
|
MOCK_RESP_WITH_ERROR = b'{"id": 0, "error": 1, "status": 1, "uid": 1}'
|
||
|
MOCK_RESP_FLEXIABLE_RESULT_LENGTH = (
|
||
|
'{"id": 0, "result": "%s", "error": null, "status": 0, "callback": null}')
|
||
|
|
||
|
class MockSocketFile:
|
||
|
|
||
|
def __init__(self, resp):
|
||
|
self.resp = resp
|
||
|
self.last_write = None
|
||
|
|
||
|
def write(self, msg):
|
||
|
self.last_write = msg
|
||
|
|
||
|
def readline(self):
|
||
|
return self.resp
|
||
|
|
||
|
def flush(self):
|
||
|
pass
|
||
|
|
||
|
def setup_mock_socket_file(self, mock_create_connection, resp=MOCK_RESP):
|
||
|
"""Sets up a fake socket file from the mock connection.
|
||
|
|
||
|
Args:
|
||
|
mock_create_connection: The mock method for creating a method.
|
||
|
resp: (str) response to give. MOCK_RESP by default.
|
||
|
|
||
|
Returns:
|
||
|
The mock file that will be injected into the code.
|
||
|
"""
|
||
|
fake_file = self.MockSocketFile(resp)
|
||
|
fake_conn = mock.MagicMock()
|
||
|
fake_conn.makefile.return_value = fake_file
|
||
|
mock_create_connection.return_value = fake_conn
|
||
|
return fake_file
|
||
|
|
||
|
def generate_rpc_response(self, response_length=1024):
|
||
|
length = response_length - len(self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH) + 2
|
||
|
chars = string.ascii_letters + string.digits
|
||
|
random_msg = ''.join(random.choice(chars) for i in range(length))
|
||
|
mock_response = self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH % random_msg
|
||
|
return bytes(mock_response, 'utf-8')
|