diff options
Diffstat (limited to '.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests')
14 files changed, 954 insertions, 0 deletions
diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py new file mode 100644 index 00000000..3c5738f7 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__init__.py @@ -0,0 +1,14 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..42b1ba1f --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/__init__.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..fa0a49cf --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_client.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..4001af86 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_dispatcher.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..8ebe0a5d --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_py2py.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..ae514606 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_server.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..594b5237 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/test_utils.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc Binary files differnew file mode 100644 index 00000000..67f39acf --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/__pycache__/utils.cpython-37.pyc diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py new file mode 100644 index 00000000..278111df --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_client.py @@ -0,0 +1,164 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +import io + +from sexpdata import Symbol + +from ..client import EPCClient +from ..handler import encode_message, unpack_message, BlockingCallback, \ + ReturnError, EPCError +from ..py3compat import Queue +from .utils import BaseTestCase + + +class FakeFile(object): + pass + + +class FakeSocket(object): + + def __init__(self): + self._queue = Queue.Queue() + self._buffer = io.BytesIO() + self.sent_message = Queue.Queue() + self._alive = True + + def makefile(self, mode, *_): + ff = FakeFile() + ff.closed = False + ff.close = lambda: None + ff.flush = lambda: None + if 'r' in mode: + ff.read = self.recv + return ff + elif 'w' in mode: + ff.write = self.sendall + return ff + + def append(self, byte): + self._queue.put(byte) + + def _pull(self): + byte = self._queue.get() + pos = self._buffer.tell() + self._buffer.write(byte) + self._buffer.seek(pos) + + def recv(self, bufsize): + while True: + if not self._alive: + return '' + got = self._buffer.read(bufsize) + if got: + return got + # Do not go to the next loop until some byte is appended + # to the queue: + self._pull() + + def sendall(self, string): + self.sent_message.put(string) + + def close(self): + self._alive = False + self.append(''.encode('ascii')) + + +class TestClient(BaseTestCase): + + def setUp(self): + self.fsock = FakeSocket() + self.next_reply = [] + self.client = EPCClient(self.fsock) + + @self.client.register_function + def echo(*a): + """Return argument unchanged.""" + return a + + def tearDown(self): + self.client.socket.close() # connection is closed by server + + def set_next_reply(self, *args): + self.next_reply.append(encode_message(*args)) + + def request(self, name, *args): + bc = BlockingCallback() + getattr(self.client, name)(*args, **bc.cbs) + self.fsock.append(self.next_reply.pop(0)) # reply comes after call! + return bc.result(timeout=self.timeout) + + def sent_message(self): + raw = self.fsock.sent_message.get(timeout=self.timeout) + (name, uid, rest) = unpack_message(raw[6:]) + if name == 'call': + rest[0] = rest[0].value() + return [name, uid] + rest + + def check_sent_message(self, name, uid, args): + sent = self.sent_message() + self.assertEqual(sent, [name, uid] + list(args)) + + def check_return(self, desired_return, name, *args): + uid = 1 + self.set_next_reply('return', uid, desired_return) + got = self.request(name, *args) + self.assertEqual(got, desired_return) + self.check_sent_message(name, uid, args) + + def test_call_return(self): + self.check_return('some value', 'call', 'dummy', [1, 2, 3]) + + def test_methods_return(self): + self.check_return([[Symbol('dummy'), [], "document"]], 'methods') + + def check_return_error(self, reply_name, name, *args): + uid = 1 + reply = 'error value' + eclass = ReturnError if reply_name == 'return-error' else EPCError + error = eclass(reply) + self.set_next_reply(reply_name, uid, reply) + try: + self.request(name, *args) + assert False, 'self.client.{0}({1}) should raise an error' \ + .format(name, args) + except Exception as got: + self.assertIsInstance(got, type(error)) + self.assertEqual(got.args, error.args) + self.check_sent_message(name, uid, args) + + def test_call_return_error(self): + self.check_return_error('return-error', 'call', 'dummy', [1, 2, 3]) + + def test_call_epc_error(self): + self.check_return_error('epc-error', 'call', 'dummy', [1, 2, 3]) + + def test_methods_return_error(self): + self.check_return_error('return-error', 'methods') + + def test_methods_epc_error(self): + self.check_return_error('epc-error', 'methods') + + def test_echo(self): + uid = 1 + self.fsock.append(encode_message('call', uid, Symbol('echo'), [55])) + self.check_sent_message('return', uid, [[55]]) + + +class TestClientClosedByClient(TestClient): + + def tearDown(self): + self.client.close() diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py new file mode 100644 index 00000000..cbce618b --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_dispatcher.py @@ -0,0 +1,58 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +from ..core import EPCDispatcher +from .utils import BaseTestCase + + +class Dummy(object): + pass + + +class TestEPCDispatcher(BaseTestCase): + + def setUp(self): + self.dispatcher = EPCDispatcher() + + def test_register_module(self): + import os + self.dispatcher.register_instance(os) + self.assertIs(self.dispatcher.get_method('chmod'), os.chmod) + + def test_register_module_with_dotted_names(self): + import os + self.dispatcher.register_instance(os, allow_dotted_names=True) + self.assertIs(self.dispatcher.get_method('path.join'), os.path.join) + + def test_error_on_private_method_access(self): + obj = Dummy() + obj._private_method = lambda: None + obj.sub = Dummy() + obj.sub._private_attribute = Dummy() + obj.sub._private_attribute.some_method = lambda: None + self.dispatcher.register_instance(obj, allow_dotted_names=True) + self.assertRaises(AttributeError, self.dispatcher.get_method, + '_private_method') + self.assertRaises(AttributeError, self.dispatcher.get_method, + 'obj.sub._private_attribute.some_method') + + def test_instance_get_method(self): + always_me = lambda: None + obj = Dummy() + obj._get_method = lambda _: always_me + self.dispatcher.register_instance(obj) + self.assertIs(self.dispatcher.get_method('x'), always_me) + self.assertIs(self.dispatcher.get_method('y'), always_me) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py new file mode 100644 index 00000000..88d2ca72 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_py2py.py @@ -0,0 +1,205 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +import os +import nose + +from ..client import EPCClient +from ..server import ThreadingEPCServer +from ..handler import ReturnError +from ..utils import newthread, callwith +from ..py3compat import Queue +from .utils import BaseTestCase, logging_to_stdout + + +def next_fib(x, fib): + if x < 2: + return x + return fib(x - 1) + fib(x - 2) + + +def fib(x): + return next_fib(x, fib) + + +class ThreadingPy2Py(object): + + """ + A class to setup connected EPC server and client in one process. + + This class is useful to use as a mix-in for test cases. + + """ + + def setup_connection(self, **kwds): + self.server = ThreadingEPCServer(('localhost', 0), **kwds) + self.server.daemon_threads = True + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + self.client_queue = q = Queue.Queue() + self.server.handle_client_connect = q.put + + self.client = EPCClient(self.server.server_address, **kwds) + + def teardown_connection(self): + self.client.close() + self.server.shutdown() + self.server.server_close() + + def wait_until_client_is_connected(self): + if not self.client_ready: + self.client_queue.get(timeout=1) + self.client_ready = True + + client_ready = False + + +class TestEPCPy2Py(ThreadingPy2Py, BaseTestCase): + + def setUp(self): + ThreadingEPCServer.allow_reuse_address = True + self.setup_connection() + + @self.client.register_function + @self.server.register_function + def echo(*a): + """Return argument unchanged.""" + return a + + @self.client.register_function + @self.server.register_function + def bad_method(*_): + """This is a bad method. Don't call!""" + raise ValueError("This is a bad method!") + + @self.server.register_function + def ping_server(x): + return self.server.clients[0].call_sync('pong_client', [x]) + + @self.client.register_function + def pong_client(x): + return self.client.call_sync('echo', [x]) + + @self.client.register_function + def ping_client(x): + return self.client.call_sync('pong_server', [x]) + + @self.server.register_function + def pong_server(x): + return self.server.clients[0].call_sync('echo', [x]) + + @self.server.register_function + def fib_server(x): + c = self.server.clients[0].call_sync + return next_fib(x, lambda x: c('fib_client', [x])) + + @self.client.register_function + def fib_client(x): + c = self.client.call_sync + return next_fib(x, lambda x: c('fib_server', [x])) + + def tearDown(self): + self.teardown_connection() + + def assert_call_return(self, call, method, args, reply, **kwds): + timeout = kwds.get('timeout', self.timeout) + self.assertEqual(call(method, args, timeout=timeout), reply) + + def assert_client_return(self, method, args, reply, **kwds): + self.assert_call_return(self.client.call_sync, + method, args, reply, **kwds) + + def assert_server_return(self, method, args, reply, **kwds): + self.wait_until_client_is_connected() + self.assert_call_return(self.server.clients[0].call_sync, + method, args, reply, **kwds) + + def check_bad_method(self, call_sync): + cm = logging_to_stdout(self.server.logger) + call_sync = callwith(cm)(call_sync) + self.assertRaises(ReturnError, call_sync, 'bad_method', [55]) + + def test_client_calls_server_echo(self): + self.assert_client_return('echo', [55], [55]) + + def test_client_calls_server_bad_method(self): + self.check_bad_method(self.client.call_sync) + + def test_server_calls_client_echo(self): + self.assert_server_return('echo', [55], [55]) + + def test_server_calls_client_bad_method(self): + self.wait_until_client_is_connected() + self.check_bad_method(self.server.clients[0].call_sync) + + max_message_limit = int('f' * 6, 16) + 1 # 16MB + large_data_limit = max_message_limit \ + / float(os.getenv('PYEPC_TEST_LARGE_DATA_DISCOUNT', '128')) + large_data_limit = int(large_data_limit) + """ + Environment variable PYEPC_TEST_LARGE_DATA_DISCOUNT controls + how large "large data" must be. Default is ``2 ** 7`` times + smaller than the maximum message length (16 MB). Setting + it to 1 must *not* fail. However, it takes long time to finish + the test (typically 100 sec when I tried). Setting this value + to less than one (e.g., 0.9) *must* fail the tests. + """ + + def check_large_data(self, assert_return): + margin = 100 # for parenthesis, "call", uid, etc. + data = "x" * (self.large_data_limit - margin) + timeout = self.timeout * 100 + assert_return('echo', [data], [data], timeout=timeout) + + def test_client_sends_large_data(self): + self.check_large_data(self.assert_client_return) + + def test_server_sends_large_data(self): + self.check_large_data(self.assert_server_return) + + def test_client_ping_pong(self): + self.assert_client_return('ping_server', [55], [55]) + + def test_server_ping_pong(self): + self.assert_server_return('ping_client', [55], [55]) + + def test_client_close_should_not_fail_even_if_not_used(self): + pass + + fibonacci = list(map(fib, range(12))) + fibonacci_min = 2 + """ + The Fibonacci test must succeeds at least until this index. + """ + + def check_fib(self, assert_return, method): + try: + for (i, f) in enumerate(self.fibonacci): + assert_return(method, [i], f) + except Queue.Empty: + if i > self.fibonacci_min: + raise nose.SkipTest( + "Test for {0} fails at {1} (> {2}), but it's OK." + .format(method, i, self.fibonacci_min)) + else: + raise # not OK + + def test_client_fib(self): + self.check_fib(self.assert_client_return, 'fib_server') + + def test_server_fib(self): + self.check_fib(self.assert_server_return, 'fib_client') diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py new file mode 100644 index 00000000..e44a796e --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_server.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +import socket + +from sexpdata import Symbol, loads + +from ..server import ThreadingEPCServer +from ..utils import newthread +from ..handler import encode_string, encode_object, BlockingCallback, \ + ReturnError, EPCError, ReturnErrorCallerUnknown, EPCErrorCallerUnknown, \ + CallerUnknown +from ..py3compat import utf8, Queue, nested +from .utils import mockedattr, logging_to_stdout, CaptureStdIO, BaseTestCase, \ + streamio + + +class TestEPCServerMisc(BaseTestCase): + + """ + Test that can be done without client. + """ + + def setUp(self): + # See: http://stackoverflow.com/questions/7720953 + ThreadingEPCServer.allow_reuse_address = True + self.server = ThreadingEPCServer(('localhost', 0)) + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + def tearDown(self): + self.server.shutdown() + self.server.server_close() + + def test_print_port(self): + stream = streamio() + self.server.print_port(stream) + self.assertEqual(stream.getvalue(), + '{0}\n'.format(self.server.server_address[1])) + + +class BaseEPCServerTestCase(BaseTestCase): + + def setUp(self): + # See: http://stackoverflow.com/questions/7720953 + ThreadingEPCServer.allow_reuse_address = True + self.server = ThreadingEPCServer(('localhost', 0)) + self.server_thread = newthread(self, target=self.server.serve_forever) + self.server_thread.start() + + def echo(*a): + """Return argument unchanged.""" + return a + + def bad_method(*_): + """This is a bad method. Don't call!""" + raise self.error_to_throw + self.error_to_throw = ValueError("This is a bad method!") + + self.server.register_function(echo) + self.server.register_function(bad_method) + + self.client = socket.create_connection(self.server.server_address) + self.client.settimeout(self.timeout) + + def tearDown(self): + self.client.shutdown(socket.SHUT_RDWR) + self.client.close() + self.server.shutdown() + self.server.server_close() + + def receive_message(self): + result = self.client.recv(1024) + self.assertEqual(int(result[:6], 16), len(result[6:])) + return loads(result[6:].decode()) # skip the length part + + def client_send(self, string): + self.client.send(encode_string(string)) + + def check_echo(self): + self.client_send('(call 1 echo (55))') + result = self.client.recv(1024) + self.assertEqual(encode_string('(return 1 (55))'), result) + + +class TestEPCServerRequestHandling(BaseEPCServerTestCase): + + """ + Test that EPCServer handles request from client properly. + """ + + def test_echo(self): + self.check_echo() + + def test_error_in_method(self): + with logging_to_stdout(self.server.logger): + self.client_send('(call 2 bad_method nil)') + result = self.client.recv(1024) + expected = encode_object([ + Symbol('return-error'), 2, repr(self.error_to_throw)]) + self.assertEqual(result, expected) + + def test_no_such_method(self): + with logging_to_stdout(self.server.logger): + self.client_send('(call 3 no_such_method nil)') + reply = self.receive_message() + self.assertEqual(reply[0], Symbol('epc-error')) + self.assertEqual(reply[1], 3) + assert 'No such method' in reply[2] + + def test_methods(self): + self.client_send('(methods 4)') + reply = self.receive_message() + self.assertEqual(reply[0], Symbol('return')) + self.assertEqual(reply[1], 4) + method = dict((m[0].value(), m[1:]) for m in reply[2]) + self.assertEqual(set(method), set(['echo', 'bad_method'])) + + actual_docs = dict( + (n, doc) for (n, (_, doc)) in method.items()) + desired_docs = dict( + (n, f.__doc__) for (n, f) in self.server.funcs.items()) + self.assertEqual(actual_docs, desired_docs) + + def test_unicode_message(self): + s = "日本語能力!!ソハンカク" + self.client_send(utf8('(call 1 echo ("{0}"))'.format(s))) + result = self.client.recv(1024) + self.assertEqual(encode_string(utf8('(return 1 ("{0}"))'.format(s))), + result) + + def test_invalid_sexp(self): + with logging_to_stdout(self.server.logger): + self.client_send('(((invalid sexp!') + reply = self.receive_message() + self.assertEqual(reply[0].value(), Symbol('epc-error').value()) + self.assertEqual(reply[1], []) # uid + assert 'Not enough closing brackets.' in reply[2] + + def check_caller_unkown(self, message, eclass, eargs): + self.check_echo() # to establish connection to client + called_with = Queue.Queue() + with nested(mockedattr(self.server.clients[0], + 'handle_error', called_with.put), + logging_to_stdout(self.server.logger)): + self.client_send(message) + error = called_with.get(True, 1) + self.assertIsInstance(error, eclass) + self.assertEqual(error.args, eargs) + + def test_return_caller_unkown(self): + self.check_caller_unkown( + '(return 0 ("some" "value"))', # uid=0 is always unkown + CallerUnknown, (['some', 'value'],)) + + def test_return_error_caller_unkown(self): + self.check_caller_unkown( + '(return-error nil "message")', + ReturnErrorCallerUnknown, ('message',)) + + def test_epc_error_caller_unkown(self): + self.check_caller_unkown( + '(epc-error nil "message")', + EPCErrorCallerUnknown, ('message',)) + + def check_invalid_call(self, make_call): + + # These are not necessary for the actual test, but rather + # to make sure that the server stays in the context of + # `logging_to_stdout` until the error is handled. See + # `called_with.get` below. + def handle_error(err): + self.assertTrue(orig_handle_error(err)) + called_with.put(err) + return True + self.check_echo() # to fetch handler + handler = self.server.clients[0] + orig_handle_error = handler.handle_error + called_with = Queue.Queue() + + # Here comes the actual test: + uid = 1 + with nested(logging_to_stdout(self.server.logger), + mockedattr(handler, 'handle_error', handle_error)): + self.client_send(make_call(uid)) + reply = self.receive_message() + called_with.get(timeout=1) # wait until the error got handled + self.assertEqual(reply[0], Symbol('epc-error')) + self.assertEqual(reply[1], uid) + + def test_invalid_call_not_enough_arguments(self): + self.check_invalid_call('(call {0} echo)'.format) + + def test_invalid_call_too_many_arguments(self): + self.check_invalid_call( + '(call {0} echo "value" "extra" "value")'.format) + + def test_invalid_methods_too_many_arguments(self): + self.check_invalid_call('(methods {0} "extra value")'.format) + + def test_log_traceback(self): + stdio = CaptureStdIO() + with nested(stdio, mockedattr(self.server, 'log_traceback', True)): + self.test_error_in_method() + log = stdio.read_stdout() + self.assertIn('ValueError: This is a bad method!', log) + self.assertIn('raise self.error_to_throw', log) + + +class TestEPCServerCallClient(BaseEPCServerTestCase): + + def setUp(self): + super(TestEPCServerCallClient, self).setUp() + self.check_echo() # to start connection, client must send something + self.handler = self.server.clients[0] + + self.callback_called_with = Queue.Queue() + self.callback = self.callback_called_with.put + + self.errback_called_with = Queue.Queue() + self.errback = self.errback_called_with.put + + def check_call_client_dummy_method(self): + (call, uid, meth, args) = self.receive_message() + self.assertIsInstance(uid, int) + self.assertEqual([call, uid, meth, args], + [Symbol('call'), uid, Symbol('dummy'), [55]]) + return uid + + def test_call_client_dummy_method(self): + self.handler.call('dummy', [55], self.callback, self.errback) + uid = self.check_call_client_dummy_method() + self.client_send('(return {0} 123)'.format(uid)) + reply = self.callback_called_with.get(True, 1) + self.assertEqual(reply, 123) + + def test_call_client_methods_info(self): + self.handler.methods(self.callback) + (methods, uid) = self.receive_message() + self.assertEqual(methods.value(), 'methods') + self.client_send('(return {0} ((dummy () "")))'.format(uid)) + reply = self.callback_called_with.get(True, 1) + self.assertEqual(reply, [[Symbol('dummy'), [], ""]]) + + def client_send_error(self, ename, uid, message): + self.client_send('({0} {1} "{2}")'.format(ename, uid, message)) + + def check_call_client_error(self, ename, eclass, message=utf8("message")): + self.handler.call('dummy', [55], self.callback, self.errback) + uid = self.check_call_client_dummy_method() + self.client_send_error(ename, uid, message) + reply = self.errback_called_with.get(True, 1) + self.assertIsInstance(reply, eclass) + self.assertEqual(reply.args, (message,)) + + def test_call_client_return_error(self): + self.check_call_client_error('return-error', ReturnError) + + def test_call_client_epc_error(self): + self.check_call_client_error('epc-error', EPCError) + + def check_dont_send_error_back(self, ename, eclass, + message=utf8("message")): + self.handler.call('dummy', [55]) # no callbacks! + uid = self.check_call_client_dummy_method() + with logging_to_stdout(self.server.logger): + self.client_send_error(ename, uid, message) + try: + result = self.client.recv(1024) + self.assertEqual(result, '') # nothing goes to client + except socket.timeout: + pass + + def test_dont_send_return_error_back(self): + self.check_dont_send_error_back('return-error', ReturnError) + + def test_dont_send_epc_error_back(self): + self.check_dont_send_error_back('epc-error', EPCError) + + def check_invalid_reply(self, make_reply, should_raise=EPCError): + bc = BlockingCallback() + self.handler.call('dummy', [55], **bc.cbs) + uid = self.check_call_client_dummy_method() + with logging_to_stdout(self.server.logger): + self.client_send(make_reply(uid)) + self.assertRaises(should_raise, bc.result, timeout=self.timeout) + + def test_invalid_return_not_enough_arguments(self): + self.check_invalid_reply('(return {0})'.format) + + def test_invalid_return_too_many_arguments(self): + self.check_invalid_reply( + '(return {0} "value" "extra" "value")'.format) + + def test_invalid_return_error_not_enough_arguments(self): + self.check_invalid_reply('(return-error {0})'.format, ReturnError) + + def test_invalid_return_error_too_many_arguments(self): + self.check_invalid_reply( + '(return-error {0} "value" "extra" "value")'.format, + ReturnError) + + def test_invalid_epc_error_not_enough_arguments(self): + self.check_invalid_reply('(epc-error {0})'.format) + + def test_invalid_epc_error_too_many_arguments(self): + self.check_invalid_reply( + '(epc-error {0} "value" "extra" "value")'.format) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py new file mode 100644 index 00000000..a485f0ca --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/test_utils.py @@ -0,0 +1,63 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +from ..utils import ThreadedIterator, LockingDict + +from .utils import BaseTestCase + + +class TestThreadedIterator(BaseTestCase): + + def check_identity(self, iterable): + lst = list(iterable) + self.assertEqual(list(ThreadedIterator(lst)), lst) + + def test_empty(self): + self.check_identity([]) + + def test_range_1(self): + self.check_identity(range(1)) + + def test_range_7(self): + self.check_identity(range(7)) + + +class TestLockingDict(BaseTestCase): + + def setUp(self): + self.ld = LockingDict() + + def check_set_items(self, items): + for (k, v) in items: + self.ld[k] = v + self.assertEqual(dict(**self.ld), dict(items)) + + def test_simple_set_items(self): + self.check_set_items(dict(a=1, b=2, c=3).items()) + + def test_simple_del_items(self): + self.test_simple_set_items() + ld = self.ld + del ld['a'] + del ld['b'] + self.assertEqual(dict(**self.ld), dict(c=3)) + + def test_simple_pop_items(self): + self.test_simple_set_items() + ld = self.ld + self.assertEqual(ld.pop('a'), 1) + self.assertEqual(ld.pop('b'), 2) + self.assertEqual(dict(**self.ld), dict(c=3)) diff --git a/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py new file mode 100644 index 00000000..c6815c64 --- /dev/null +++ b/.emacs.d.back/.python-environments/default/lib/python3.7/site-packages/epc/tests/utils.py @@ -0,0 +1,127 @@ +# Copyright (C) 2012- Takafumi Arakaki + +# 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 3 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, see <http://www.gnu.org/licenses/>. + + +import os +import sys +import functools +import io + +try: + import unittest + unittest.TestCase.assertIs +except AttributeError: + import unittest2 as unittest +from contextlib import contextmanager + +from ..py3compat import Queue, PY3 +from ..utils import newthread + + +@contextmanager +def mockedattr(object, name, replace): + """ + Mock `object.name` attribute using `replace`. + """ + original = getattr(object, name) + try: + setattr(object, name, replace) + yield + finally: + setattr(object, name, original) + + +def logging_to_stdout(logger): + # it assumes that 0-th hander is the only one stream handler... + return mockedattr(logger.handlers[0], 'stream', sys.stdout) + + +def streamio(): + """ + Return `io.StringIO` for Python 3, otherwise `io.BytesIO`. + """ + if PY3: + return io.StringIO() + else: + return io.BytesIO() + + +class CaptureStdIO(object): + + def __enter__(self): + self._orig_stdin = sys.stdin + self._orig_stdout = sys.stdout + self._orig_stderr = sys.stderr + + self.stdin = sys.stdin = streamio() + self.stdout = sys.stdout = streamio() + self.stderr = sys.stderr = streamio() + return self + + def __exit__(self, exc_type, exc_value, traceback): + sys.stdin = self._orig_stdin + sys.stdout = self._orig_stdout + sys.stderr = self._orig_stderr + + def read_stdout(self): + self.stdout.seek(0) + return self.stdout.read() + + def read_stderr(self): + self.stderr.seek(0) + return self.stderr.read() + + +class BaseTestCase(unittest.TestCase): + + TRAVIS = os.getenv('TRAVIS') + + if TRAVIS: + timeout = 10 + else: + timeout = 1 + + +def skip(reason): + from nose import SkipTest + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwds): + raise SkipTest("Skipping {0} because: {1}" + .format(func.__name__, reason)) + return wrapper + return decorator + + +def post_mortem_in_thread(traceback): + """ + `pdb.post_mortem` that can be used in a daemon thread. + + Put the following in the `except`-block:: + + import sys + from epc.tests.utils import post_mortem_in_thread + exc_info = sys.exc_info() + post_mortem_in_thread(exc_info[2]) + + """ + import pdb + blocker = Queue.Queue() + thread = newthread(target=blocker.get) + thread.daemon = False + thread.start() + pdb.post_mortem(traceback) + blocker.put(None) |