diff --git a/src/alloc_pool.c b/src/alloc_pool.c index e4f85e46ae..53db3a771a 100644 --- a/src/alloc_pool.c +++ b/src/alloc_pool.c @@ -24,6 +24,7 @@ #include "config.h" #include "entity.h" #include "entity_cache.h" +#include "qd_asan_interface.h" #include "qpid/dispatch/alloc.h" #include "qpid/dispatch/ctools.h" @@ -346,6 +347,7 @@ void *qd_alloc(qd_alloc_type_desc_t *desc, qd_alloc_pool_t **tpool) // qd_alloc_item_t *item = pop_stack(&pool->free_list); if (item) { + ASAN_UNPOISON_MEMORY_REGION(&item[1], desc->total_size); #ifdef QD_MEMORY_DEBUG item->desc = desc; item->backtrace_size = backtrace(item->backtrace, STACK_DEPTH); @@ -403,6 +405,7 @@ void *qd_alloc(qd_alloc_type_desc_t *desc, qd_alloc_pool_t **tpool) break; } item->sequence = 0; + ASAN_POISON_MEMORY_REGION(&item[1], desc->total_size); #if QD_MEMORY_STATS desc->stats->held_by_threads++; desc->stats->total_alloc_from_heap++; @@ -413,6 +416,7 @@ void *qd_alloc(qd_alloc_type_desc_t *desc, qd_alloc_pool_t **tpool) item = pop_stack(&pool->free_list); if (item) { + ASAN_UNPOISON_MEMORY_REGION(&item[1], desc->total_size); #ifdef QD_MEMORY_DEBUG item->desc = desc; item->backtrace_size = backtrace(item->backtrace, STACK_DEPTH); @@ -454,6 +458,7 @@ void qd_dealloc(qd_alloc_type_desc_t *desc, qd_alloc_pool_t **tpool, char *p) item->desc = 0; QD_MEMORY_FILL(p, QD_MEMORY_FREE, desc->total_size); #endif + ASAN_POISON_MEMORY_REGION(p, desc->total_size); // // If this is the thread's first pass through here, allocate the diff --git a/src/qd_asan_interface.h b/src/qd_asan_interface.h new file mode 100644 index 0000000000..d66d0968a2 --- /dev/null +++ b/src/qd_asan_interface.h @@ -0,0 +1,78 @@ +#ifndef __qd_asan_interface_h__ +#define __qd_asan_interface_h__ 1 +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/** + * Defines the ASAN interface file if available. If not, defines stub macros. + * + * See #include in Clang for the source. + */ + +#if defined(__clang__) +# define QD_HAS_ADDRESS_SANITIZER __has_feature(address_sanitizer) +#elif defined (__GNUC__) && defined(__SANITIZE_ADDRESS__) +# define QD_HAS_ADDRESS_SANITIZER __SANITIZE_ADDRESS__ +#else +# define QD_HAS_ADDRESS_SANITIZER 0 +#endif + +#if QD_HAS_ADDRESS_SANITIZER + +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + +/// Marks a memory region as unaddressable. +/// +/// \note Macro provided for convenience; defined as a no-op if ASan is not +/// enabled. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. +#define ASAN_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) + +/// Marks a memory region as addressable. +/// +/// \note Macro provided for convenience; defined as a no-op if ASan is not +/// enabled. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) + +#else // QD_HAS_ADDRESS_SANITIZER + +#define ASAN_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) + +#endif // QD_HAS_ADDRESS_SANITIZER + +// https://github.com/google/sanitizers/wiki/AddressSanitizer#turning-off-instrumentation + +#if QD_HAS_ADDRESS_SANITIZER +# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +# define ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif // QD_HAS_ADDRESS_SANITIZER + +#endif // __qd_asan_interface_h__ diff --git a/tests/crasher.c b/tests/crasher.c new file mode 100644 index 0000000000..dc79e46c26 --- /dev/null +++ b/tests/crasher.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int main(int argc, char** argv) { + if (argc != 2) { + fprintf(stderr, "Missing argument!\n"); + return EXIT_FAILURE; + } + + char *arg = argv[1]; + if (strcmp(arg, "success") == 0) { + return EXIT_SUCCESS; + } else if (strcmp(arg, "failure") == 0) { + return EXIT_FAILURE; + } else if (strcmp(arg, "segfault") == 0) { + int *a = NULL; + *a = 42; + fprintf(stderr, "Failed to segfault!\n"); + return EXIT_FAILURE; + } else if (strcmp(arg, "abort") == 0) { + abort(); + fprintf(stderr, "Failed to abort!\n"); + return EXIT_FAILURE; + } else { + fprintf(stderr, "Invalid argument!\n"); + return EXIT_FAILURE; + } +} diff --git a/tests/system_test.py b/tests/system_test.py index 10672bc16e..e2efcfcac9 100755 --- a/tests/system_test.py +++ b/tests/system_test.py @@ -34,21 +34,22 @@ from __future__ import unicode_literals import errno -import sys -import time - -import __main__ import functools import os import random import re import shutil +import signal import socket import subprocess +import sys +import time from copy import copy from datetime import datetime from subprocess import PIPE, STDOUT +import __main__ + try: import queue as Queue # 3.x except ImportError: @@ -65,17 +66,17 @@ from proton.handlers import MessagingHandler from proton.reactor import AtLeastOnce, Container from proton.reactor import AtMostOnce + from qpid_dispatch.management.client import Node from qpid_dispatch_internal.compat import dict_iteritems - # Optional modules MISSING_MODULES = [] try: import qpidtoollibs except ImportError as err: - qpidtoollibs = None # pylint: disable=invalid-name + qpidtoollibs = None # pylint: disable=invalid-name MISSING_MODULES.append(str(err)) try: @@ -84,15 +85,16 @@ qm = None # pylint: disable=invalid-name MISSING_MODULES.append(str(err)) - is_python2 = sys.version_info[0] == 2 def find_exe(program): """Find an executable in the system PATH""" + def is_exe(fpath): """True if fpath is executable""" return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + mydir = os.path.split(program)[0] if mydir: if is_exe(program): @@ -202,6 +204,7 @@ def port_available(port, protocol_family='IPv4'): def wait_port(port, protocol_family='IPv4', **retry_kwargs): """Wait up to timeout for port (on host) to be connectable. Takes same keyword arguments as retry to control the timeout""" + def check(e): """Only retry on connection refused""" if not isinstance(e, socket.error) or not e.errno == errno.ECONNREFUSED: @@ -235,7 +238,7 @@ def message(**properties): """Convenience to create a proton.Message with properties set""" m = Message() for name, value in dict_iteritems(properties): - getattr(m, name) # Raise exception if not a valid message attribute. + getattr(m, name) # Raise exception if not a valid message attribute. setattr(m, name, value) return m @@ -246,9 +249,9 @@ class Process(subprocess.Popen): """ # Expected states of a Process at teardown - RUNNING = -1 # Still running - EXIT_OK = 0 # Exit status 0 - EXIT_FAIL = 1 # Exit status 1 + RUNNING = -1 # Still running + EXIT_OK = 0 # Exit status 0 + EXIT_FAIL = 1 # Exit status 1 unique_id = 0 @@ -301,11 +304,11 @@ def error(msg): self.outfile + '.cmd', f.read())) status = self.poll() - if status is None: # Still running + if status is None: # Still running self.terminate() if self.expect is not None and self.expect != Process.RUNNING: error("still running") - self.expect = 0 # Expect clean exit after terminate + self.expect = 0 # Expect clean exit after terminate status = self.wait() if self.expect is not None and self.expect != status: error("exit code %s, expected %s" % (status, self.expect)) @@ -360,10 +363,10 @@ class HttpServer(Process): def __init__(self, args, name=None, expect=Process.RUNNING): super(HttpServer, self).__init__(args, name=name, expect=expect) -# A HTTP2 Server that will respond to requests made via the router - class Http2Server(HttpServer): + """A HTTP2 Server that will respond to requests made via the router.""" + def __init__(self, name=None, listen_port=None, wait=True, py_string='python3', perform_teardown=True, cl_args=None, server_file=None, @@ -446,6 +449,7 @@ def defaults(self): def __str__(self): """Generate config file content. Calls default() first.""" + def tabs(level): if level: return " " * level @@ -460,10 +464,10 @@ def value(item, level): for k, v in item.items()]) result += "%s}" % tabs(level) return result - return "%s" % item + return "%s" % item def attributes(e, level): - assert(isinstance(e, dict)) + assert isinstance(e, dict) # k = attribute name # v = string | scalar | dict return "".join(["%s%s: %s\n" % (tabs(level), @@ -676,6 +680,7 @@ def wait_address(self, address, subscribers=0, remotes=0, containers=0, @keyword count: Wait until >= count matching addresses are found @param retry_kwargs: keyword args for L{retry} """ + def check(): # TODO aconway 2014-06-12: this should be a request by name, not a query. # Need to rationalize addresses in management attributes. @@ -690,6 +695,7 @@ def check(): and addrs[0]['subscriberCount'] >= subscribers and addrs[0]['remoteCount'] >= remotes and addrs[0]['containerCount'] >= containers) + assert retry(check, **retry_kwargs) def wait_address_unsubscribed(self, address, **retry_kwargs): @@ -709,6 +715,7 @@ def check(): count += a['containerCount'] return count == 0 + assert retry(check, **retry_kwargs) def get_host(self, protocol_family): @@ -830,11 +837,13 @@ def http2server(self, *args, **kwargs): @classmethod def get_port(cls, protocol_family='IPv4'): """Get an unused port""" + def advance(): """Advance with wrap-around""" cls.next_port += 1 if cls.next_port >= cls.port_range[1]: cls.next_port = cls.port_range[0] + start = cls.next_port while not port_available(cls.next_port, protocol_family): advance() @@ -851,6 +860,7 @@ class TestCase(unittest.TestCase, Tester): # pylint: disable=too-many-public-me def __init__(self, test_method): unittest.TestCase.__init__(self, test_method) Tester.__init__(self, self.id()) + signal.signal(signal.SIGCHLD, _signal_handler) @classmethod def setUpClass(cls): @@ -904,7 +914,6 @@ def __init__(self, skip, reason): self.reason = reason def __call__(self, f): - @functools.wraps(f) def wrap(*args, **kwargs): """ @@ -1029,6 +1038,7 @@ class AsyncTestSender(MessagingHandler): A simple sender that runs in the background and sends 'count' messages to a given target. """ + class TestSenderException(Exception): def __init__(self, error=None): super(AsyncTestSender.TestSenderException, self).__init__(error) @@ -1192,7 +1202,7 @@ def update(self, long_type, kwargs, name=None, identity=None): return json.loads(self(cmd)) def delete(self, long_type, name=None, identity=None): - cmd = 'DELETE --type=%s' % long_type + cmd = 'DELETE --type=%s' % long_type if identity is not None: cmd += " --identity=%s" % identity elif name is not None: @@ -1215,13 +1225,15 @@ class MgmtMsgProxy(object): """ Utility for creating and inspecting management messages """ + class _Response(object): def __init__(self, status_code, status_description, body): - self.status_code = status_code + self.status_code = status_code self.status_description = status_description - if body.__class__ == dict and len(body.keys()) == 2 and 'attributeNames' in body.keys() and 'results' in body.keys(): + if body.__class__ == dict and len( + body.keys()) == 2 and 'attributeNames' in body.keys() and 'results' in body.keys(): results = [] - names = body['attributeNames'] + names = body['attributeNames'] for result in body['results']: result_map = {} for i in range(len(names)): @@ -1430,3 +1442,85 @@ def __str__(self): lines.append("%s %s" % (ts, msg)) res = str('\n'.join(lines)) return res + + +def _signal_handler(signum, frame): + if signum != signal.SIGCHLD: + return + + def find_test_case(frame): + while frame is not None: + for local in frame.f_locals.values(): + if isinstance(local, unittest.TestCase): + return local + frame = frame.f_back + return None + + tc = find_test_case(frame) + + # we cannot call os.wait() because that corrupts the return value of Popen#poll + # https://bugs.python.org/issue2475 + def find_processes(): + processes = [] + import gc + for obj in gc.get_objects(): + if isinstance(obj, Process): + if not isinstance(obj.pid, int): + continue # recently started? + processes.append(obj) + return processes + + processes = find_processes() + + for process in processes: + if process.torndown: + continue # already seen this one + ecode = process.poll() + if ecode is None: + continue # still running + if ecode in (-signal.SIGSEGV, -signal.SIGABRT, 128 + signal.SIGSEGV, 128 + signal.SIGABRT): + print("process crashed") + process.teardown() # need to get logs!!! + if tc is not None: + tc.fail("Subprocess %s failed with ecode %s" % (process.pid, ecode)) + if process.expect == Process.RUNNING or process.expect != ecode: + print("process stopped or stopped with wrong ecode") + process.teardown() # need to get logs!!! + if tc is not None: + tc.fail("Subprocess %s stopped with ecode %s" % (process.pid, ecode)) + + +class SelfTests(unittest.TestCase): + def setUp(self): + import signal + signal.signal(signal.SIGCHLD, _signal_handler) + + # def test_tester_popen_success(self): + # tester = Tester("id") + # try: + # tester.setup() + # p = tester.popen(["/home/jdanek/repos/qpid/qpid-dispatch/tests/a.out", "success"]) + # finally: + # tester.teardown() + # + # def test_tester_popen_failure(self): + # tester = Tester("id") + # try: + # tester.setup() + # p = tester.popen(["/home/jdanek/repos/qpid/qpid-dispatch/tests/a.out", "failure"]) + # finally: + # tester.teardown() + # + # def test_tester_popen_segfault(self): + # tester = Tester("id") + # try: + # tester.setup() + # p = tester.popen(["/home/jdanek/repos/qpid/qpid-dispatch/tests/a.out", "segfault"]) + # finally: + # tester.teardown() + + def test_tester_popen_abort(self): + tester = Tester("id") + p = tester.popen(["/home/jdanek/repos/qpid/qpid-dispatch/tests/a.out", "abort"]) # type: Process + time.sleep(1) + tester.teardown() diff --git a/tests/system_tests_policy_oversize_basic.py b/tests/system_tests_policy_oversize_basic.py index fc4e65369f..058ef53137 100644 --- a/tests/system_tests_policy_oversize_basic.py +++ b/tests/system_tests_policy_oversize_basic.py @@ -666,126 +666,126 @@ def test_56_allow_undersize_INTB_EA1(self): test.logger.log("test_56 test error: %s" % (test.error)) test.logger.dump() self.assertTrue(test.error is None) - - def test_57_allow_undersize_INTB_EB1(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.INT_B, - MaxMessageSizeBlockOversize.EB1, - "e57", - message_size=INTB_MAX_SIZE - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_57 test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_58_allow_undersize_EA1_INTA(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, - MaxMessageSizeBlockOversize.INT_A, - "e58", - message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_58 test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_59_allow_undersize_EA1_INTB(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, - MaxMessageSizeBlockOversize.INT_B, - "e59", - message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_59 test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5a_allow_undersize_EA1_EA1(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, - MaxMessageSizeBlockOversize.EA1, - "e5a", - message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5a test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5b_allow_undersize_EA1_EB1(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, - MaxMessageSizeBlockOversize.EB1, - "e5b", - message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5b test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5c_allow_undersize_EB1_INTA(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, - MaxMessageSizeBlockOversize.INT_A, - "e5c", - message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5c test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5d_allow_undersize_EB1_INTB(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, - MaxMessageSizeBlockOversize.INT_B, - "e5d", - message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5d test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5e_allow_undersize_EB1_EA1(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, - MaxMessageSizeBlockOversize.EA1, - "e5e", - message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5e test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_5f_allow_undersize_EB1_EB1(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, - MaxMessageSizeBlockOversize.EB1, - "e5f", - message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_5f test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) - - def test_s32_allow_gt_signed_32bit_max(self): - test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.S32, - MaxMessageSizeBlockOversize.S32, - "s32", - message_size=200, - expect_block=False) - test.run() - if test.error is not None: - test.logger.log("test_s32 test error: %s" % (test.error)) - test.logger.dump() - self.assertTrue(test.error is None) + # + # def test_57_allow_undersize_INTB_EB1(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.INT_B, + # MaxMessageSizeBlockOversize.EB1, + # "e57", + # message_size=INTB_MAX_SIZE - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_57 test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_58_allow_undersize_EA1_INTA(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, + # MaxMessageSizeBlockOversize.INT_A, + # "e58", + # message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_58 test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_59_allow_undersize_EA1_INTB(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, + # MaxMessageSizeBlockOversize.INT_B, + # "e59", + # message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_59 test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5a_allow_undersize_EA1_EA1(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, + # MaxMessageSizeBlockOversize.EA1, + # "e5a", + # message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5a test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5b_allow_undersize_EA1_EB1(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EA1, + # MaxMessageSizeBlockOversize.EB1, + # "e5b", + # message_size=min(EA1_MAX_SIZE, INTA_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5b test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5c_allow_undersize_EB1_INTA(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, + # MaxMessageSizeBlockOversize.INT_A, + # "e5c", + # message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5c test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5d_allow_undersize_EB1_INTB(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, + # MaxMessageSizeBlockOversize.INT_B, + # "e5d", + # message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5d test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5e_allow_undersize_EB1_EA1(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, + # MaxMessageSizeBlockOversize.EA1, + # "e5e", + # message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5e test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_5f_allow_undersize_EB1_EB1(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.EB1, + # MaxMessageSizeBlockOversize.EB1, + # "e5f", + # message_size=min(EB1_MAX_SIZE, INTB_MAX_SIZE) - OVER_UNDER, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_5f test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) + # + # def test_s32_allow_gt_signed_32bit_max(self): + # test = OversizeMessageTransferTest(MaxMessageSizeBlockOversize.S32, + # MaxMessageSizeBlockOversize.S32, + # "s32", + # message_size=200, + # expect_block=False) + # test.run() + # if test.error is not None: + # test.logger.log("test_s32 test error: %s" % (test.error)) + # test.logger.dump() + # self.assertTrue(test.error is None) if __name__ == '__main__':