def should_throw_alg_exception_if_packet_seen_before_password(): engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # scenario: gruel_recv happens without a password having been set b_error = False try: r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_heartbeat_payload())) except: b_error = True if b_error: return True else: log('expected an exception, did not get one') return False
def should_attempt_connection(): addr = '127.0.0.1' port = 4098 # engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_client = prop_gruel_client_new(engine=engine, gruel_press=gruel_press, gruel_puff=gruel_puff) # connection_info = ConnectionInfo() doc_receiver = DocReceiver() # # connection attempt assert 0 == len(engine.events) prop_gruel_client.attempt_connection( addr=addr, port=port, password='******', cb_connect=connection_info.on_tcp_connect, cb_condrop=connection_info.on_tcp_condrop, cb_doc=doc_receiver.on_doc) # # confirm effects assert 0 == connection_info.calls_to_on_condrop assert 0 == connection_info.calls_to_on_connect assert 1 == len(engine.events) assert engine.events[-1] == ('open_tcp_client', addr, port) assert prop_gruel_client.get_status() == 'attempting_tcp_connection' # return True
def should_construct_and_start_and_stop(): addr = '127.0.0.1' port = 5000 username = '******' password = '******' r = receiver_cog_fake(cog_h='receiver', orb=None, engine=None) # engine = engine_fake() activity = activity_new() # # scenario: construction gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_server = prop_gruel_server_new(engine=engine, cb_doc_recv=r.on_doc_recv) # # scenario: start and stop without crashing start_server(engine=engine, prop_gruel_server=prop_gruel_server, addr=addr, port=port, password=password) stop_server(prop_gruel_server=prop_gruel_server) # return True
def should_clear_state_in_announce_connect(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # r.nc_announce_tcp_connect( ip='does not matter', port=1234) assert 1 == r.count_nearnote() # r.nc_announce_tcp_condrop() assert 2 == r.count_nearnote() # return True
def should_store_password_values(): engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # scenario: password message our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # confirm effects assert server_customs_cog.expected_password == our_password # return True
def should_send_gruel_send_data_to_a_connected_client(): gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) # engine = engine_fake() nearcast_schema = gs_nearcast_schema_new() snoop = nearcast_snoop_fake(nearcast_schema=nearcast_schema) snoop.disable() orb = nearcast_orb_new(engine=engine, nearcast_schema=nearcast_schema, nearcast_snoop=snoop) r = orb.init_cog(fn=receiver_cog_fake) tcp_server_cog = orb.init_cog(fn=tcp_server_cog_new) # addr = '127.0.0.1' port = 5000 password = '******' # # confirm starting state assert 0 == r.count_announce_tcp_connect() assert tcp_server_cog.server_sid == None assert tcp_server_cog.client_sid == None # # scenario: start the server start_service(orb=orb, ip=addr, port=port, password=password) # # confirm effects assert 0 == r.count_announce_tcp_connect() assert tcp_server_cog.server_sid != None assert tcp_server_cog.client_sid == None # # scenario: client connects client_addr = '203.15.93.150' client_port = 6000 simulate_client_connect(engine=engine, orb=orb, tcp_server_cog=tcp_server_cog, ip=client_addr, port=client_port) # # confirm baseline assert 1 == r.count_announce_tcp_connect() assert tcp_server_cog.server_sid == None assert tcp_server_cog.client_sid != None # # scenario: tcp_server_cog gets gruel_send but client is not connected r.nc_gruel_send(payload=gruel_press.create_client_login_payload( password='******', heartbeat_interval=4)) orb.cycle() # # confirm effects: client should still be connected, and we should have # sent no packets to the engine. assert tcp_server_cog.server_sid == None assert tcp_server_cog.client_sid != None assert 1 == len(engine.sent_data) # return True
def should_run_a_rejection_sequence(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' usr_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # confirm effects: see a assert 0 == clock.now() # # scenario: rejection is sequenced server_customs_cog._to_rejection( s='triggered by test') # # nothing should have changed assert 0 == r.count_gruel_send() assert 0 == r.count_please_tcp_boot() # # at three seconds we should see server_bye but no boot clock.inc(3) orb.cycle() assert 1 == r.count_gruel_send() d_gruel = gruel_puff.unpack( payload=r.last_gruel_send()) assert d_gruel['message_h'] == 'server_bye' assert 0 == r.count_please_tcp_boot() # # at four seconds we should see the boot clock.inc(1) orb.cycle() assert 1 == r.count_please_tcp_boot() # return True
def should_start_at_dormant_status(): engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_client = prop_gruel_client_new(engine=engine, gruel_press=gruel_press, gruel_puff=gruel_puff) # # confirm status assert prop_gruel_client.get_status() == 'dormant' # return True
def simulate_client_send_login(engine, orb, tcp_server_cog, pw, hbint): gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) # payload = gruel_press.create_client_login_payload(password=pw, heartbeat_interval=hbint) cs_tcp_recv = CsTcpRecv() cs_tcp_recv.engine = engine cs_tcp_recv.client_sid = create_sid() cs_tcp_recv.data = payload tcp_server_cog._engine_on_tcp_recv(cs_tcp_recv=cs_tcp_recv) orb.cycle()
def should_do_basic_login_reject(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' usr_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # check starting position assert 0 == r.count_please_tcp_boot() # # scenario: user sends an invalid password r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_client_login_payload( password=usr_password, heartbeat_interval=3))) orb.cycle() # # check effects: we should boot the client assert server_customs_cog.state == ServerCustomsState.reject_stage_a assert 0 == r.count_gruel_send() # return True
def should_do_successful_login_accept(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # scenario: user sends an valid password r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_client_login_payload( password=our_password, heartbeat_interval=3))) orb.cycle() # # confirm effects assert server_customs_cog.state == ServerCustomsState.authorised assert 1 == r.count_announce_login() assert 1 == r.count_gruel_send() d_grual = gruel_puff.unpack(r.last_gruel_send()) assert d_grual['message_h'] == 'server_greet' # return True
def should_return_to_dormant_on_failed_connection(): addr = '127.0.0.1' port = 4098 # engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_client = prop_gruel_client_new(engine=engine, gruel_press=gruel_press, gruel_puff=gruel_puff) # connection_info = ConnectionInfo() doc_receiver = DocReceiver() # # connection attempt assert 0 == len(engine.events) prop_gruel_client.attempt_connection( addr=addr, port=port, password='******', cb_connect=connection_info.on_tcp_connect, cb_condrop=connection_info.on_tcp_condrop, cb_doc=doc_receiver.on_doc) # # confirm effects assert prop_gruel_client.get_status() == 'attempting_tcp_connection' # # simulate the engine rejecting the connection cs_tcp_condrop = cs.CsTcpCondrop() cs_tcp_condrop.engine = engine cs_tcp_condrop.sid = uniq() cs_tcp_condrop.message = 'test123' prop_gruel_client._engine_on_tcp_condrop(cs_tcp_condrop=cs_tcp_condrop) # # confirm effects assert 0 == connection_info.calls_to_on_connect assert 1 == connection_info.calls_to_on_condrop assert prop_gruel_client.get_status() == 'dormant' # return True
def should_boot_user_on_receipt_of_login_message_when_already_logged_in(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # hack the starting position server_customs_cog.state = ServerCustomsState.authorised # # scenario: send a message that is client_login r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_client_login_payload( password=our_password, heartbeat_interval=3))) orb.cycle() # # check effects assert server_customs_cog.state == ServerCustomsState.reject_stage_a # return True
def should_boot_client_if_first_message_is_not_client_login(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # check starting position assert 0 == r.count_please_tcp_boot() # # scenario: first message is not client_login r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_heartbeat_payload())) orb.cycle() # # check effects assert server_customs_cog.expected_password == our_password # return True
def should_handle_successful_tcp_connection(): addr = '127.0.0.1' port = 4098 # engine = engine_fake() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_client = prop_gruel_client_new(engine=engine, gruel_press=gruel_press, gruel_puff=gruel_puff) # connection_info = ConnectionInfo() doc_receiver = DocReceiver() # # connection attempt assert 0 == len(engine.events) prop_gruel_client.attempt_connection( addr=addr, port=port, password='******', cb_connect=connection_info.on_tcp_connect, cb_condrop=connection_info.on_tcp_condrop, cb_doc=doc_receiver.on_doc) # # have engine indicate connection success cs_tcp_connect = cs.CsTcpConnect() cs_tcp_connect.engine = engine cs_tcp_connect.sid = uniq() cs_tcp_connect.message = 'test123' prop_gruel_client._engine_on_tcp_connect(cs_tcp_connect=cs_tcp_connect) # # confirm effects assert 1 == connection_info.calls_to_on_connect assert 0 == connection_info.calls_to_on_condrop assert prop_gruel_client.get_status() == 'ready_to_attempt_login' # return True
def should_simulate_common_behaviour(): MAX_PACKET_LEN = 800 # # get our engine going engine = engine_fake() clock = engine.get_clock() # gruel_schema = gruel_schema_new() gruel_press = gruel_press_new(gruel_schema=gruel_schema, mtu=MTU) gruel_puff = gruel_puff_new(gruel_schema=gruel_schema, mtu=MTU) prop_gruel_client = prop_gruel_client_new(engine=engine, gruel_press=gruel_press, gruel_puff=gruel_puff) assert prop_gruel_client.heartbeat_interval == 1 # # other bits we'll need activity = activity_new() connection_info = ConnectionInfo() doc_receiver = DocReceiver() # # scenario: connection attempt assert 0 == len(engine.events) addr = '127.0.0.1' port = 4098 password = '******' prop_gruel_client.attempt_connection( addr=addr, port=port, password=password, cb_connect=connection_info.on_tcp_connect, cb_condrop=connection_info.on_tcp_condrop, cb_doc=doc_receiver.on_doc) # # scenario: successful connection # (here we simulate the engine calling back to the client to say # that there connection was successful) clock.set(5) cs_tcp_connect = cs.CsTcpConnect() cs_tcp_connect.engine = engine cs_tcp_connect.sid = uniq() cs_tcp_connect.message = 'test123' prop_gruel_client._engine_on_tcp_connect(cs_tcp_connect=cs_tcp_connect) # # confirm effects assert prop_gruel_client.get_status() == 'ready_to_attempt_login' assert prop_gruel_client.last_heartbeat_recv == 5 assert prop_gruel_client.last_heartbeat_sent == 5 # # give the client a turn so it can move to logging in. prop_gruel_client.at_turn(activity=activity) # # confirm effects assert activity.get()[-1] == 'PropGruelClient/sending login' assert prop_gruel_client.get_status() == 'login_message_in_flight' # # do we see the login message in-flight? assert 1 == len(engine.sent_data) latest_payload = engine.sent_data[-1] d_client_login = gruel_puff.unpack(payload=latest_payload) assert d_client_login['message_h'] == 'client_login' assert d_client_login['password'] == password assert d_client_login['heartbeat_interval'] == 1 # # simulate server sending back a successful login. (first, we create # the kind of payload that the server would have created in this # circumstance. Then we call back to the client in the same way that # a real engine would call back to it.) def server_sends_greet_payload(): server_greet_payload = gruel_press.create_server_greet_payload( max_packet_size=MAX_PACKET_LEN) cs_tcp_recv = cs.CsTcpRecv() cs_tcp_recv.engine = engine cs_tcp_recv.client_sid = 'fake_sid' cs_tcp_recv.data = server_greet_payload prop_gruel_client._engine_on_tcp_recv(cs_tcp_recv=cs_tcp_recv) server_sends_greet_payload() # # confirm effects assert prop_gruel_client.get_status() == 'streaming' # # scenario: server sends a heartbeat clock.set(10) def server_sends_heartbeat(): server_heartbeat = gruel_press.create_heartbeat_payload() cs_tcp_recv = cs.CsTcpRecv() cs_tcp_recv.engine = engine cs_tcp_recv.client_sid = 'fake_sid' cs_tcp_recv.data = server_heartbeat prop_gruel_client._engine_on_tcp_recv(cs_tcp_recv=cs_tcp_recv) server_sends_heartbeat() # # confirm effects assert prop_gruel_client.get_status() == 'streaming' assert prop_gruel_client.last_heartbeat_recv == 10 # # scenario: client should send a heartbeat clock.set(11) prop_gruel_client.at_turn(activity=activity) # # confirm effects assert 2 == len(engine.sent_data) payload = engine.sent_data[-1] d_payload = gruel_puff.unpack(payload=payload) assert d_payload['message_h'] == 'heartbeat' # # confirm that it now does not send another one prop_gruel_client.at_turn(activity=activity) assert 2 == len(engine.sent_data) # # scenario: client sends a small payload small_doc = ''' i greet message greet "hello, world!" ''' mcount_before = len(engine.sent_data) prop_gruel_client.send_document(doc=small_doc) prop_gruel_client.at_turn(activity=activity) # # confirm effects assert len(engine.sent_data) == (mcount_before + 1) payload = engine.sent_data[-1] d_payload = gruel_puff.unpack(payload=payload) assert d_payload['message_h'] == 'docdata' assert d_payload['b_complete'] == 1 assert d_payload['data'] == small_doc # # scenario: client sends a payload that must span several # packets large_doc = 'w/%s/y' % ('x' * (2 * MAX_PACKET_LEN)) mcount_before = len(engine.sent_data) prop_gruel_client.send_document(doc=large_doc) # give it several turns to allow doc to be dispatched prop_gruel_client.at_turn(activity) prop_gruel_client.at_turn(activity) prop_gruel_client.at_turn(activity) # # confirm effects assert len(engine.sent_data) > mcount_before # (inspect first packet) d_payload = gruel_puff.unpack(payload=engine.sent_data[mcount_before]) assert d_payload['message_h'] == 'docdata' assert d_payload['b_complete'] == 0 assert d_payload['data'][0] == 'w' # (inspect next-to-last packet) d_payload = gruel_puff.unpack(payload=engine.sent_data[-2]) assert d_payload['message_h'] == 'docdata' assert d_payload['b_complete'] == 0 assert d_payload['data'][-1] == 'x' # (inspect last packet) d_payload = gruel_puff.unpack(payload=engine.sent_data[-1]) assert d_payload['message_h'] == 'docdata' assert d_payload['b_complete'] == 1 assert d_payload['data'][-1] == 'y' # # scenario: client receives a single-packet payload from server docs_received = len(doc_receiver.docs) small_doc = ''' i arbitrary message arbitrary "message content" ''' def server_sends_small_payload(): payload = gruel_press.create_docdata_payload(b_complete=1, data=small_doc) cs_tcp_recv = cs.CsTcpRecv() cs_tcp_recv.engine = engine cs_tcp_recv.client_sid = 'fake_sid' cs_tcp_recv.data = payload prop_gruel_client._engine_on_tcp_recv(cs_tcp_recv=cs_tcp_recv) server_sends_small_payload() # # confirm effects assert len(doc_receiver.docs) == docs_received + 1 assert doc_receiver.docs[-1] == small_doc # # scenario: client receives a multi-packet doc that requires # buffering on the client side docs_received = len(doc_receiver.docs) large_doc_segments = 'h/%s/j' % ('i' * (2 * MAX_PACKET_LEN)) large_doc = ''.join(large_doc_segments) def server_sends_large_doc(): remaining = large_doc_segments to_send = deque() while remaining != '': doc = remaining[:50] remaining = remaining[50:] to_send.append(doc) while to_send: docpart = to_send.popleft() b_complete = 0 if not to_send: b_complete = 1 # payload = gruel_press.create_docdata_payload(b_complete=b_complete, data=docpart) # cs_tcp_recv = cs.CsTcpRecv() cs_tcp_recv.engine = engine cs_tcp_recv.client_sid = 'fake_sid' cs_tcp_recv.data = payload prop_gruel_client._engine_on_tcp_recv(cs_tcp_recv=cs_tcp_recv) server_sends_large_doc() # # confirm effects assert len(doc_receiver.docs) > docs_received assert doc_receiver.docs[-1] == large_doc # return True
def should_send_a_couple_of_docs(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # preparation: user logs in r.nc_announce_tcp_connect( ip='also not important', port=456) r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_client_login_payload( password=our_password, heartbeat_interval=3))) orb.cycle() # # confirm assumptions assert 1 == r.count_gruel_send() # # scenario: we send a large outbound document towards customs doc = '/'.join( ['x', 'y'*2000, 'z'] ) r.nc_doc_send( doc=doc) # # confirm effects: expect to see the doc broken up into several pieces assert 2 <= r.count_gruel_send() # examine first doc packet d_gruel = gruel_puff.unpack(r.get_gruel_send()[1]) assert d_gruel['message_h'] == 'docdata' assert d_gruel['b_complete'] == 0 assert d_gruel['data'][0] == 'x' # examine next-to-last doc packet d_gruel = gruel_puff.unpack(r.get_gruel_send()[-2]) assert d_gruel['message_h'] == 'docdata' assert d_gruel['b_complete'] == 0 assert d_gruel['data'][-1] == 'y' # examine last doc packet d_gruel = gruel_puff.unpack(r.get_gruel_send()[-1]) assert d_gruel['message_h'] == 'docdata' assert d_gruel['b_complete'] == 1 assert d_gruel['data'][-1] == 'z' # return True
def should_buffer_a_couple_of_docs(): engine = engine_fake() clock = engine.get_clock() gruel_schema = gruel_schema_new() gruel_press = gruel_press_new( gruel_schema=gruel_schema, mtu=engine.mtu) gruel_puff = gruel_puff_new( gruel_schema=gruel_schema, mtu=engine.mtu) # orb = nearcast_orb_new( engine=engine, nearcast_schema=gs_nearcast_schema_new()) server_customs_cog = orb.init_cog( fn=server_customs_cog_new) r = orb.init_cog( fn=receiver_cog_fake) # # start the service our_password = '******' r.nc_start_service( ip='does not matter', port=1234, password=our_password) # # preparation: user logs in r.nc_announce_tcp_connect( ip='also not important', port=456) r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_client_login_payload( password=our_password, heartbeat_interval=3))) orb.cycle() # # scenario: user sends part of a doc r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_docdata_payload( b_complete=0, data='123'))) orb.cycle() # # confirm effects (doc is not complete, so should be no effects) assert 0 == r.count_doc_recv() # # scenario: now finish the first doc r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_docdata_payload( b_complete=1, data='456'))) orb.cycle() # # confirm effects (doc is not complete, so should be no effects) assert 1 == r.count_doc_recv() assert r.last_doc_recv() == '123456' # # scenario: now send a second doc, and check it's correct r.nc_gruel_recv( d_gruel=gruel_puff.unpack( payload=gruel_press.create_docdata_payload( b_complete=1, data='here is a doc'))) orb.cycle() # # confirm effects assert 2 == r.count_doc_recv() assert r.last_doc_recv() == 'here is a doc' # return True