예제 #1
0
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
예제 #2
0
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
예제 #3
0
파일: prop.py 프로젝트: petr-tik/solent
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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()
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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
예제 #15
0
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
예제 #16
0
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
예제 #17
0
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
예제 #18
0
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