def test_tnet_string(): testvec = [ "The π character is called pi", ] successes = 0 for t in testvec: with tnet.tnet_machine() as tnsmach: path = "test_tnet" tns = tnetstrings.dump( t ) data = cpppo.dotdict() source = cpppo.peekable( tns ) for mch, sta in tnsmach.run( source=source, data=data, path=path ): log.info( "%s byte %5d: data: %r", misc.centeraxis( mch, 25, clip=True ), source.sent, data ) log.info("Parsing tnetstring:\n%s\n%s (byte %d)", repr(bytes(tns)), '-' * (len(repr(bytes(tns[:source.sent])))-1) + '^', source.sent ) if sta is None or not sta.terminal: # Ended in a non-terminal state log.info( "%s byte %5d: failure: data: %r; Not terminal; unrecognized", misc.centeraxis( tnsmach, 25, clip=True ), source.sent, data ) else: # Ended in a terminal state. if source.peek() is None: log.info( "%s byte %5d: success: data: %r", misc.centeraxis( tnsmach, 25, clip=True ), source.sent, data ) successes += 1 else: log.info( "%s byte %5d: failure: data: %r; Terminal, but TNET string wasn't consumed", misc.centeraxis( tnsmach, 25, clip=True ), source.sent, data ) assert successes == len( testvec )
def test_tnetstrings(): tests = [ (8, 'abcπ'), (38, { "pi": 'π', "abc": b'abc', "def": str("def") }), (3, []), (26, [1, 2.3, str("4"), b'5', '6']), (3, None), (7, True), ] composite = b'' for l, t in tests: data = tnetstrings.dump(t, encoding="utf-8") logging.info("%32.32r == %r" % (t, data)) assert type(data) is bytes assert len(data) == l composite += data ti = iter(tests) extra = composite while extra: payload, extra = tnetstrings.parse(extra, encoding="utf-8") l, t = next(ti) assert payload == t
def test_tnetstrings(): tests = [ ( 8, 'abcπ' ), ( 38, { "pi": 'π', "abc": b'abc', "def": str("def") } ), ( 3, [] ), ( 26, [1, 2.3, str("4"), b'5', '6'] ), ( 3, None ), ( 7, True ), ] composite = b'' for l, t in tests: data = tnetstrings.dump( t, encoding="utf-8" ) logging.info( "%32.32r == %r" % ( t, data )) assert type( data ) is bytes assert len( data ) == l composite += data ti = iter( tests ) extra = composite while extra: payload, extra = tnetstrings.parse( extra, encoding="utf-8" ) l, t = next( ti ) assert payload == t
def tnet_cli(number, tests=None): log.info("%3d client connecting... PID [%5d]", number, os.getpid()) conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect(tnet.address) log.info("%3d client connected", number) rcvd = '' try: eof = False for t in tests: msg = tnetstrings.dump(t) while len(msg) and not eof: out = min(len(msg), random.randrange(*charrange)) log.info("Tnet Client %3d send: %5d/%5d: %s", number, out, len(msg), cpppo.reprlib.repr(msg[:out])) conn.sendall(msg[:out]) msg = msg[out:] # Await inter-block chardelay if output remains, otherwise await # final response before dropping out to shutdown/drain/close. # If we drop out immediately and send a socket.shutdown, it'll # sometimes deliver a reset to the server end of the socket, # before delivering the last of the data. rpy = network.recv( conn, timeout=chardelay if len(msg) else draindelay) if rpy is not None: eof = not len(rpy) log.info("Tnet Client %3d recv: %5d: %s", number, len(rpy), "EOF" if eof else cpppo.reprlib.repr(rpy)) rcvd += rpy.decode("utf-8") if eof: break log.normal("Tnet Client %3d done; %s", number, "due to EOF" if eof else "normal termination") except KeyboardInterrupt as exc: log.normal("%3d client terminated: %r", number, exc) except Exception as exc: log.warning("%3d client failed: %r\n%s", number, exc, traceback.format_exc()) finally: # One or more packets may be in flight; wait 'til we timeout/EOF rpy = network.drain(conn, timeout=draindelay) log.info("Tnet Client %3d drain %5d: %s", number, len(rpy) if rpy is not None else 0, cpppo.reprlib.repr(rpy)) if rpy is not None: rcvd += rpy.decode("utf-8") # Count the number of successfully matched JSON decodes successes = 0 i = 0 for i, (t, r) in enumerate(zip(tests, rcvd.split('\n\n'))): e = json.dumps(t) log.info("%3d test #%3d: %32s --> %s", number, i, cpppo.reprlib.repr(t), cpppo.reprlib.repr(e)) if r == e: successes += 1 else: log.warning("%3d test #%3d: %32s got %s", number, i, cpppo.reprlib.repr(t), cpppo.reprlib.repr(e)) failed = successes != len(tests) if failed: log.warning("%3d client failed: %d/%d tests succeeded", number, successes, len(tests)) log.info("%3d client exited", number) return failed
def tnet_cli( number, tests=None ): log.info( "%3d client connecting... PID [%5d]", number, os.getpid() ) conn = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) conn.connect( tnet.address ) log.info( "%3d client connected", number ) rcvd = '' try: eof = False for t in tests: msg = tnetstrings.dump( t ) log.normal( "Tnet Client %3d send: %5d: %s (from data: %s)", number, len( msg ), cpppo.reprlib.repr( msg ), cpppo.reprlib.repr( t )) while len( msg ) and not eof: out = min( len( msg ), random.randrange( *charrange )) conn.send( msg[:out] ) msg = msg[out:] # Await inter-block chardelay if output remains, otherwise await # final response before dropping out to shutdown/drain/close. # If we drop out immediately and send a socket.shutdown, it'll # sometimes deliver a reset to the server end of the socket, # before delivering the last of the data. rpy = network.recv( conn, timeout=chardelay if len( msg ) else draindelay ) if rpy is not None: eof = not len( rpy ) log.info( "Tnet Client %3d recv: %5d: %s", number, len( rpy ), "EOF" if eof else cpppo.reprlib.repr( rpy )) rcvd += rpy.decode( "utf-8" ) if eof: break log.normal( "Tnet Client %3d done; %s", number, "due to EOF" if eof else "normal termination" ) except KeyboardInterrupt as exc: log.normal( "%3d client terminated: %r", number, exc ) except Exception as exc: log.warning( "%3d client failed: %r\n%s", number, exc, traceback.format_exc() ) finally: # One or more packets may be in flight; wait 'til we timeout/EOF rpy = network.drain( conn, timeout=draindelay ) log.info( "Tnet Client %3d drain %5d: %s", number, len( rpy ) if rpy is not None else 0, cpppo.reprlib.repr( rpy )) if rpy is not None: rcvd += rpy.decode( "utf-8" ) # Count the number of successfully matched JSON decodes successes = 0 i = 0 for i, (t, r) in enumerate( zip( tests, rcvd.split( '\n\n' ))): e = json.dumps( t ) log.info( "%3d test #%3d: %32s --> %s", number, i, cpppo.reprlib.repr( t ), cpppo.reprlib.repr( e )) if r == e: successes += 1 else: log.warning( "%3d test #%3d: %32s got %s", number, i, cpppo.reprlib.repr( t ), cpppo.reprlib.repr( e )) failed = successes != len( tests ) if failed: log.warning( "%3d client failed: %d/%d tests succeeded", number, successes, len( tests )) log.info( "%3d client exited", number ) return failed