""" 
<Program Name>
  z_test_client_process.repy

<Started>
  February 12, 2009

<Author>
  Richard Jordan

<Purpose>
  To test that Client.process() function works.

  Passes quietly
"""
include constants.repy
include client.repy
include test_packet_factory.repy

if callfunc == 'initialize':
  IP = 'whatever'
  PORT = 12345

def test_pp_synack_new():
  SEQ_NUM = 1
  cli = TcpClient(None)
  CLI_SEQ = 4
  cli.last_seq_sent = CLI_SEQ
  ACK_NUM = CLI_SEQ + 1
  WINDOW = 10
  assert not cli.last_ack_recv
  assert not cli.send_window_size
  pack = mycontext['tpf'].synack(SEQ_NUM, ACK_NUM, WINDOW)
  assert cli.process(pack)
  assert cli.send_window_size == WINDOW
  assert cli.last_ack_recv == ACK_NUM
  assert cli.last_seq_sent == CLI_SEQ

def test_pp_synack_old():
  SEQ_NUM = 1
  WINDOW = 10
  cli = TcpClient(None)
  CLI_SEQ = 4
  cli.last_seq_sent = CLI_SEQ
  ACK_NUM = CLI_SEQ + 1
  cli.last_ack_recv = ACK_NUM
  pack = mycontext['tpf'].synack(SEQ_NUM, ACK_NUM, WINDOW)
  assert cli.process(pack)
  assert cli.send_window_size == WINDOW
  assert cli.last_ack_recv == ACK_NUM
  assert cli.last_seq_sent == CLI_SEQ

def test_pp_synack_bad():
  SEQ_NUM = 1
  cli = TcpClient(None)
  CLI_SEQ = 4
  cli.last_seq_sent = CLI_SEQ
  ACK_NUM = CLI_SEQ + 1
  BAD_ACK_NUM = CLI_SEQ
  pack = mycontext['tpf'].synack(SEQ_NUM, BAD_ACK_NUM)
  assert not cli.process(pack)
  assert not cli.send_window_size
  assert not cli.last_ack_recv
  assert cli.last_seq_sent == CLI_SEQ

def test_pp_ack():
  ACK_NUM = 1
  SEQ_NUM = 5
  NEXT_ACK = SEQ_NUM + 1
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  cli.last_ack_recv = ACK_NUM
  pack = mycontext['tpf'].ack(NEXT_ACK)
  cli.process(pack)
  assert cli.last_ack_recv == NEXT_ACK
  assert cli.last_seq_sent == SEQ_NUM

def test_pp_ack_new_window():
  ACK_NUM = 1
  SEQ_NUM = 5
  NEXT_ACK = SEQ_NUM + 1
  WINDOW = 10
  NEW_WINDOW = 10
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  cli.last_ack_recv = ACK_NUM
  cli.send_window_size = WINDOW
  pack = mycontext['tpf'].ack(NEXT_ACK, NEW_WINDOW)
  cli.process(pack)
  assert cli.send_window_size == NEW_WINDOW

def test_pp_ack_of_syn():
  SEQ_NUM = 5
  ACK_NUM = SEQ_NUM + 1
  WIN = 10
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  assert not cli.last_ack_recv
  assert not cli.send_window_size
  pack = mycontext['tpf'].ack(ACK_NUM, WIN)
  cli.process(pack)
  assert cli.last_ack_recv == ACK_NUM
  assert cli.last_seq_sent == SEQ_NUM
  assert cli.send_window_size == WIN

def test_pp_old_ack_of_syn():
  SEQ_NUM = 5
  ACK_NUM = SEQ_NUM + 1
  WIN = 10
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  cli.last_ack_recv = ACK_NUM
  cli.send_window_size = WIN
  pack = mycontext['tpf'].ack(ACK_NUM, WIN)
  cli.process(pack)
  assert cli.last_ack_recv == ACK_NUM
  assert cli.last_seq_sent == SEQ_NUM
  assert cli.send_window_size == WIN

def test_pp_bad_ack_of_syn():
  SEQ_NUM = 5
  BAD_ACK_NUM = 2
  WIN = 10
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  assert not cli.last_ack_recv
  assert not cli.send_window_size
  pack = mycontext['tpf'].ack(BAD_ACK_NUM, WIN)
  cli.process(pack)
  assert not cli.last_ack_recv
  assert cli.last_seq_sent == SEQ_NUM
  assert not cli.send_window_size

def test_pp_payloadack():
  NUM = 100 # whatever

  SEQ_NUM = 5
  ACK_NUM = 6
  WIN = 10
  SS = 2
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  assert not cli.last_ack_recv
  assert not cli.send_window_size
  pack = mycontext['tpf'].psh(NUM, SS)
  pack.window = WIN
  cli.process(pack)
  assert cli.last_ack_recv == ACK_NUM
  assert cli.last_seq_sent == SEQ_NUM
  assert cli.send_window_size == WIN

def test_pp_ack_mod():
  ACK_NUM = MAX_SEQ_NUM - 2
  SEQ_NUM = 2
  NEXT_ACK = 1
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  cli.last_ack_recv = ACK_NUM
  pack = mycontext['tpf'].ack(NEXT_ACK)
  cli.process(pack)
  assert cli.last_ack_recv == NEXT_ACK
  assert cli.last_seq_sent == SEQ_NUM

def test_pp_ack_cumulative_mod():
  ACK_NUM = MAX_SEQ_NUM - 2
  SEQ_NUM = 2
  NEXT_ACK = 1
  cli = TcpClient(None)
  cli.last_seq_sent = SEQ_NUM
  cli.last_ack_recv = ACK_NUM
  cli.packet_cache[MAX_SEQ_NUM-2] = True
  cli.packet_cache[MAX_SEQ_NUM-1] = True
  cli.packet_cache[0] = True
  cli.packet_cache[1] = True
  cli.packet_cache[2] = True
  pack = mycontext['tpf'].ack(NEXT_ACK)
  cli.process(pack)
  assert cli.last_ack_recv == NEXT_ACK
  assert cli.last_seq_sent == SEQ_NUM
  assert not (MAX_SEQ_NUM-2) in cli.packet_cache.keys()
  assert not (MAX_SEQ_NUM-1) in cli.packet_cache.keys()
  assert not 0 in cli.packet_cache.keys()
  assert cli.packet_cache[1]
  assert cli.packet_cache[2]

####################
# Test Helper Functions
####################

def main():
  # setup
  mycontext['tpf'] = TestPacketFactory(PORT)

  # Run tests
  test_pp_synack_new()
  test_pp_synack_old()
  test_pp_synack_bad()
  test_pp_ack()
  test_pp_ack_new_window()
  test_pp_ack_of_syn()
  test_pp_bad_ack_of_syn()
  test_pp_payloadack()
#  test_pp_old_ack_of_syn_after_payack()
  test_pp_old_ack_of_syn()
  test_pp_ack_mod()
  test_pp_ack_cumulative_mod()

  # teardown
  exitall()

if callfunc == 'initialize':
  main()
