# File covered: evlMain.c

# http://www.tcl.tk/cgi-bin/tct/tip/85.html

set pathToTestFiles "./src/ucode/"

proc dummy { aPkt aMgr } {
  return 
}

if {[lsearch [namespace children] ::tcltest] == -1} {
  package require tcltest
  namespace import -force ::tcltest::*
}

proc check { testId result expectedResult commands} {
  if { $result != $expectedResult } {
    puts "Test $testId failed"
    puts "\tExpected result=$expectedResult, actual result=$result"
    puts "commands were $commands"
  } else {
    puts "Test $testId passed"
  }
}

proc approxCheck { result expectedResult } {
  puts "result is $result, expectedResult is $expectedResult"
  if { $result == 0 } {
    return 0
  }
  set percDiff [expr ( $result - $expectedResult ) / $result ]
  if { $percDiff < 0.1 } {
    return 1
  }
  return 0
}


proc qTest { } {
  global pathToTestFiles
  
  # add the above check to the set of checkers, invoke as -match approx
  customMatch approx approxCheck
  
  set iBufSize 	  7
  set oBufSize 	  7
  set actionBufSize 7
  
  set numIterations 100
  
  set ppCacheSize 100
  
  set basicSlice 0.1
  set getPacketsWeight 1
  set computeActionsWeight 1
  set performActionsWeight 1
  set queuingWeight 1
  set writePacketsWeight 1

  # important to set this right, otherwise it defaults to 1, leads to only one pkt being processed
  set maxNumPktsToRead 7

  
  set recordPktsWritten 1
  
  set rText {
    queue q0 type:cos; numclasses:2; priority:0;
    queue q1 type:flow; flowtype:srcip; priority:0;
    queue q2 type:cos; numclasses:2; priority:0;
    queue q3 type:flow; flowtype:srcip; priority:0;
  
    tcp any 0 -> any any ( ) queue:q0; class:1;
    tcp any 1 -> any any ( ) queue:q0; class:0;
    tcp any any -> any any () queue:q1; 
    tcp any any -> any any () queue:q2; class:0;
    tcp any 2 -> any any () queue:q3;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-1 \
  			{simple COS check} \
  			$rText \
  			$pText \
  			{6,0,1,2,3,4,5} ] 
  
  
  set rText {
    queue q1 type:flow; flowtype:srcdesttcpip; priority:0;
  
    tcp any any -> any any ( ) queue:q1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-2 \
  			{simple DRR check} \
  			$rText \
  			$pText \
  			{0,4,1,5,2,6,3} ] 
  
  
  set rText {
    queue q1 type:flow; flowtype:srcip; priority:0;
  
    tcp any any -> any any ( ) queue:q1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:1; destport:0; srcip:0.0.0.1; destip:0.0.0.0; } 
  }
  
  
  lappend TESTS [  list 	evlMain-3 \
  			{DRR check on just srcips} \
  			$rText \
  			$pText \
  			{0,6,1,2,3,4,5} ] 
  
  
  set rText {
    queue q1 type:flow; flowtype:destip; priority:0;
  
    tcp any any -> any any ( ) queue:q1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; destport:1; srcip:1.1.1.1; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; destport:2; srcip:0.0.1.1; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; destport:3; srcip:1.1.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; destport:4; srcip:1.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:1; destport:5; srcip:0.1.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:1; destport:6; srcip:0.0.1.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:1; destport:7; srcip:0.0.0.1; destip:0.0.0.1; } 
  }
  
  
  lappend TESTS [  list 	evlMain-4 \
  			{DRR check on just destips} \
  			$rText \
  			$pText \
  			{0,6,1,2,3,4,5} ] 
  
  set rText {
    queue q1 type:flow; flowtype:srcdestip; priority:0;
  
    tcp any any -> any any ( ) queue:q1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; destport:1; srcip:1.1.1.1; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; destport:2; srcip:1.1.1.1; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; destport:3; srcip:1.1.1.1; destip:1.1.1.1; } 
   { ack:3; protocol:tcp; srcport:0; destport:4; srcip:1.1.1.1; destip:1.1.1.1; } 
   { ack:4; protocol:tcp; srcport:1; destport:5; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:1; destport:6; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:1; destport:7; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  
  lappend TESTS [  list 	evlMain-5 \
  			{DRR check on just srcdestips} \
  			$rText \
  			$pText \
  			{0,2,4,1,3,5,6} ] 
  
  set rText {
    queue q1 type:flow; flowtype:desttcpip; priority:0;
  
    tcp any any -> any any ( ) queue:q1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:0; destport:0; srcip:1.1.1.1; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:0; destport:0; srcip:1.1.1.1; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:0; destport:0; srcip:1.1.1.1; destip:1.1.1.1; } 
   { ack:3; protocol:tcp; srcport:0; destport:0; srcip:1.1.1.1; destip:1.1.1.1; } 
   { ack:4; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:0; destport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  
  lappend TESTS [  list 	evlMain-6 \
  			{DRR check on just desttcpip} \
  			$rText \
  			$pText \
  			{0,2,1,3,4,5,6} ] 
  
  
  set rText {
    queue q0 type:cos; numclasses:2; priority:0;
    queue q1 type:cos; numclasses:2; priority:0;
  
    tcp any 0 -> any any ( ) queue:q0; class:0;
    tcp any 1 -> any any ( ) queue:q0; class:1;
    tcp any 0 -> any any () queue:q1; class:0; 
    tcp any 1 -> any any () queue:q1; class:1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-7 \
  			{two COS queues} \
  			$rText \
  			$pText \
  			{3,4,5,6,0,1,2} ] 
  
  
  set rText {
    queue q0 type:cos; numclasses:2; priority:10;
    queue q1 type:cos; numclasses:2; priority:0;
  
    tcp any 0 -> any any () queue:q0; class:0;
    tcp any 1 -> any any () queue:q0; class:1;
    tcp any 1 -> any any () queue:q1; class:0; 
    tcp any 0 -> any any () queue:q1; class:1;
  }
  
  set pText { 
   { ack:0; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; }
   { ack:1; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:2; protocol:tcp; srcport:1; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:3; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:4; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:5; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
   { ack:6; protocol:tcp; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-8 \
  			{two COS queues} \
  			$rText \
  			$pText \
  			{0,1,2,3,4,5,6} ] 
  
  # tests connected to rate computation
  
  set rText { 
    queue q0 type:cos; numclasses:2; priority:0; maxbytes:10000; drop:red; 
    queue q1 type:flow; flowtype:srcip; flowmaxrate:100; maxflows:100; numclasses:2; priority:0; drop:red;
    queue q2 type:cos; numclasses:4; priority:0; drop:tail; maxbytes:1000;
    
    tcp 192.168.1.1 any -> any any ( ) queue:q0; class:0; 
    tcp 192.168.1.1 any -> any any ( ) queue:q0; class:0; 
    tcp 192.168.1.1 any -> any any ( ) queue:q1; class:0; 
    tcp 192.168.1.1 any -> any any ( ) queue:q2; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.0; size:4; content:a000;} 
    { ack:1; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.1; size:4; content:b000; } 
    { ack:2; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.2; size:4; content:c000; } 
    { ack:3; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.3; size:4; content:d000; } 
    { ack:4; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.4; size:4; content:e000; } 
    { ack:5; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.5; size:4; content:f000; } 
    { ack:6; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.6; size:4; content:g000; } 
    { ack:7; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.7; size:4; content:h000; } 
    { ack:8; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.8; size:4; content:i000; } 
    { ack:9; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.9; size:4; content:j000; } 
    { ack:10; protocol:tcp; srcip:192.168.1.1; destip:0.0.0.10; size:2; content:k000; } 
  }
  
  lappend TESTS [  list 	evlMain-9 \
  			{buffer size related tests} \
  			$rText \
  			$pText \
  			{0,1,2,3,4,5,6} ] 
  
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:1; 
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp;  }
    { ack:1; protocol:tcp; }
  }
  
  lappend TESTS [  list 	evlMain-10 \
  			{buffer size related tests } \
  			$rText \
  			$pText \
  			{} \
  			{set maxNumPktsToRead 1; set numIterations 20; set iBufSize 100; set oBufSize 10; set actionBufSize 1000; } ] 
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:100;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:1000; content:bar;}
    { ack:2; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-11 \
  			{check buffer capacity limits} \
  			$rText \
  			$pText \
  			{0} \
  			{set maxNumPktsToRead 3; set numIterations 5; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:128;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:1000; content:bar;}
    { ack:2; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-12 \
  			{check buffer capacity limits} \
  			$rText \
  			$pText \
  			{0,2} \
  			{set maxNumPktsToRead 3; set numIterations 5; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:127;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:10; content:bar;}
    { ack:2; protocol:tcp; size:9; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-13 \
  			{check buffer capacity limits} \
  			$rText \
  			$pText \
  			{0,2} \
  			{set maxNumPktsToRead 3; set numIterations 5; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  # note - the result is {0} because the first packet is already in the queue
  # when we try to add the second (which fails because it exceeeds
  # the capacity) and also the thirs (since the firrst is in the
  # queue, the added number of bytes becomes 128, exactly the limit
  # of the queue size, causing RED to drop)
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; drop:red; maxbytes:128;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:1024; content:bar;}
    { ack:2; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-14 \
  			{check buffer capacity limits with RED} \
  			$rText \
  			$pText \
  			{0} \
  			{set maxNumPktsToRead 3; set numIterations 10; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; drop:red; maxbytes:1024;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:1024; content:bar;}
    { ack:2; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-15 \
  			{ check buffer capacity limits with RED; there is a small chance that the \
  			  third packet may be dropped because of RED, so the test may fail } \
  			$rText \
  			$pText \
  			{0,2} \
  			{set maxNumPktsToRead 3; set numIterations 10; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; drop:red; maxbytes:256;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:10; content:bar;}
    { ack:2; protocol:tcp; size:70; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-16 \
  			{ check buffer capacity limits with RED; there is a small chance that the \
  			  third packet may be accepted because of RED, so the test may fail } \
  			$rText \
  			$pText \
  			{0,1} \
  			{set maxNumPktsToRead 3; set numIterations 3; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  #### 17
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; windowduration:1.0; maxbytes:100000000; maxrate:5120;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:10; content:adnan;}
    { ack:1; protocol:tcp; size:10; content:bar;}
  }
  
  lappend TESTS [  list 	evlMain-17 \
  			{ check rate limits - approx } \
  			$rText \
  			$pText \
  			{5120.0} \
  			{set recordStats 1; set basicSlice 0.01; set maxNumPktsToRead 2; set numIterations 20; set iBufSize 100; set oBufSize 100; set actionBufSize 100; set pktProcessPoolSize 100; } ] 
  
  #### 18
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:1000000; maxrate:80000;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:946; content:adnan;}
  }
  
  lappend TESTS [  list 	evlMain-18 \
  			{ check rate limits - approx } \
  			$rText \
  			$pText \
  			{80000.1} \
  			{set recordStats 1; set basicSlice 0.1; set maxNumPktsToRead 10; set numIterations 10; set iBufSize 100; set oBufSize 100; set actionBufSize 100; set pktProcessPoolSize 100; } ] 
  
  #### 19
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:1000000; maxrate:80000;
    queue q1 type:cos; numclasses:1; priority:0; maxbytes:1000000; maxrate:80000;
    tcp any any -> any any ( ) queue:q0; class:0; 
    tcp any any -> any any ( ) queue:q1; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:946; content:adnan;}
  }
  
  lappend TESTS [  list 	evlMain-20 \
  			{ check rate limits -approx } \
  			$rText \
  			$pText \
  			{80000.0} \
  			{set recordStats 1; set basicSlice 1.0; set maxNumPktsToRead 10; set numIterations 10000; set iBufSize 100000; set oBufSize 1000000; set actionBufSize 100000; set pktProcessPoolSize 10000; } ] 
  
  
  #### 20
  
  set rText { 
    queue q0 type:cos; numclasses:1; priority:0; maxbytes:1000000; maxrate:80000;
    queue q1 type:cos; numclasses:1; priority:0; 
    tcp any any -> any any ( content:"adnan"; ) queue:q0; class:0; 
    tcp any any -> any any ( content:"aziz"; ) queue:q1; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; size:946; content:adnan;}
    { ack:1; protocol:tcp; size:946; content:aziz;}
  }
  
  lappend TESTS [  list 	evlMain-20 \
  			{ check rate limits } \
  			$rText \
  			$pText \
  			{0,1,1,1,1,1,0,0,0,0} \
  			{set recordStats 0; set basicSlice 10.0; set maxNumPktsToRead 10; set numIterations 10000000; set iBufSize 1000; set oBufSize 1000; set actionBufSize 1000; set pktProcessPoolSize 100000; } ] 
  
  #### 21-1
  
  set rText { 
    queue q0 type:flow; flowtype:srcdesttcpip; priority:0; maxflows:6;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; }
    { ack:1; protocol:tcp; destport:1; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:2; protocol:tcp; destport:2; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:3; protocol:tcp; destport:3; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:4; protocol:tcp; destport:4; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:5; protocol:tcp; destport:5; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:6; protocol:tcp; destport:6; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-21-1 \
  			{flow limit} \
  			$rText \
  			$pText \
  			{0,1,2,3,4,5} \
  			{set recordStats 0; set basicSlice 1.0; set maxNumPktsToRead 7; set numIterations 1000; set iBufSize 10; set oBufSize 10; set actionBufSize 10; set pktProcessPoolSize 10; } ] 
  
  
  
  
  #### 21-2
  
  set rText { 
    queue q0 type:flow; flowtype:srcdesttcpip; priority:0; maxflows:7;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; }
    { ack:1; protocol:tcp; destport:1; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:2; protocol:tcp; destport:2; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:3; protocol:tcp; destport:3; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:4; protocol:tcp; destport:4; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:5; protocol:tcp; destport:5; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
    { ack:6; protocol:tcp; destport:6; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; } 
  }
  
  lappend TESTS [  list 	evlMain-21-2 \
  			{flow limit} \
  			$rText \
  			$pText \
  			{0,1,2,3,4,5,6} \
  			{set recordStats 0; set basicSlice 1.0; set maxNumPktsToRead 7; set numIterations 1000; set iBufSize 10; set oBufSize 10; set actionBufSize 10; set pktProcessPoolSize 10; } ] 
  
  
  #### 22
  
  set rText { 
    queue q0 type:flow; flowtype:srcdesttcpip; priority:0; maxflows:7; maxbytesperflow:128; flowdrop:tail;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:10; content:"adnan"; }
    { ack:1; protocol:tcp; destport:1; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:10; content:"adnan"; } 
    { ack:2; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:100; content:"adnan"; } 
    { ack:3; protocol:tcp; destport:1; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:100; content:"adnan"; } 
    { ack:4; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:10; content:"adnan"; } 
    { ack:5; protocol:tcp; destport:1; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:10; content:"adnan"; } 
    { ack:6; protocol:tcp; destport:0; srcport:0; srcip:0.0.0.0; destip:0.0.0.0; size:1000; content:"adnan"; } 
  }
  
  lappend TESTS [  list 	evlMain-22 \
  			{flow limit on number of flows, bytes per flow} \
  			$rText \
  			$pText \
  			{0,1,4,5} \
  			{set recordStats 0; set basicSlice 1.0; set maxNumPktsToRead 7; set numIterations 1000; set iBufSize 10; set oBufSize 10; set actionBufSize 10; set pktProcessPoolSize 10; } ] 
  
  
  # 23
  
  set rText { 
    queue q0 type:flow; flowtype:srcip; drop:red; numclasses:1; priority:0; maxbytes:1120;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; srcip:0.0.0.0; protocol:tcp; size:10; content:adnan;}
    { ack:1; srcip:0.0.0.0; protocol:tcp; size:1000; content:bar;}
    { ack:2; srcip:0.0.0.0; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-23 \
  			{check buffer capacity limits in per flow queueing, 
  			  using red so small fail prob} \
  			$rText \
  			$pText \
  			{0,2} \
  			{set maxNumPktsToRead 3; set numIterations 5; set iBufSize 3; set oBufSize 3; set actionBufSize 3; } ] 
  
  # 24
  
  set rText { 
    queue q0 type:flow; flowtype:srcip; drop:red; numclasses:1; priority:0; maxbytes:1120;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; srcip:0.0.0.0; protocol:tcp; size:10; content:adnan;}
    { ack:1; srcip:0.0.0.0; protocol:tcp; size:1000; content:bar;}
    { ack:2; srcip:0.0.0.0; protocol:tcp; size:10; content:car;}
  }
  
  lappend TESTS [  list 	evlMain-24 \
  			{check buffer capacity limits in per flow queueing} \
  			$rText \
  			$pText \
  			{0,2,0,2,0,2,0} \
  			{set maxNumPktsToRead 10; set numIterations 5; set iBufSize 3; set oBufSize 3; set actionBufSize 3; set ppCacheSize 100; } ] 
  
  
  # 25
  
  set rText { 
    # queue q0 type:flow; flowtype:srcip; drop:red; numclasses:1; priority:0; maxbytes:1120;
    queue q0 type:flow; flowtype:srcip; drop:red; numclasses:1; priority:0; maxbytes:1120;
    tcp any any -> any any ( ) queue:q0; class:0; 
  }
  
  set pText { 
    { ack:0; srcip:0.0.0.0; protocol:tcp; size:500; content:adnan;}
    { ack:1; srcip:0.0.0.0; protocol:tcp; size:500; content:bar;}
    { ack:2; srcip:0.0.0.0; protocol:tcp; size:10; content:car;}
  }
  
  # daisy, e4300 report 0,2,2,2,0,2,2,1,2,2 --- seems reasonable
  lappend TESTS [  list 	evlMain-25 \
  			{check buffer capacity limits in per flow queueing} \
  			$rText \
  			$pText \
  			{0,2,2,2,0,2,2,1,2,2} \
  			{set maxNumPktsToRead 10; set numIterations 1000; set iBufSize 10; set oBufSize 100; set actionBufSize 100; set ppCacheSize 1000;} ] 
  
  
  # 26-1
  
  set rText { 
    # queue q0 type:flow; flowtype:srcip; drop:red; numclasses:1; priority:0; maxbytes:1120;
    ip any any -> any any ( ) tcl-ext:dummy;
  }
  
  set pText { 
    { ack:0; srcip:0.0.0.0; protocol:tcp; size:12; content:adnanaziz123;}
  }
  
  lappend TESTS [  list 	evlMain-26-1 \
  			{check en/decrypt} \
  			$rText \
  			$pText \
  			{0} \
  			{set maxNumPktsToRead 1; set numIterations 1000; set iBufSize 10; set oBufSize 100; set actionBufSize 100; set ppCacheSize 1000;} ] 
  
  
  # 28-1
  
# run the tests
  
# used to control whether we dynamically link in code
set doDL 1 
  
foreach aTest $TESTS {
  set testId [lindex $aTest 0]
  set testLabel [lindex $aTest 1]
  
    if {1 || [regexp {evlMain\-26-1} $testId ] } {
  
      puts "Entering $testId\t($testLabel)"
  
      set rulesText [lindex $aTest 2]
      puts "rules text is $rulesText"
  
      set pktArrayText [lindex $aTest 3]
      puts "pkt text is $pktArrayText"
  
      set expectedResult [lindex $aTest 4]
      puts "expectedResult is $expectedResult"
  
      set commands [lindex $aTest 5 ]
      puts "commands are $commands"
      eval $commands
  
      set pktArray [createPktArrayFromText $pktArrayText]
      set mgr [evlBuildManagerFromText $rulesText]
  
  
      if { [regexp {flow\ limit} $testLabel ] } {
        puts "\tRunning $testId\t($testLabel)"
        test $testId $testLabel -body {evlRoute $mgr $pktArray } -result $expectedResult
      } elseif { [regexp {approx} $testLabel ] } { 
         puts "\tRunning $testId\t($testLabel)"
         puts "Approx check, expexted result is $expectedResult"
         test $testId $testLabel -body {evlRoute $mgr $pktArray }  -result $expectedResult  -match approx
         # test $testId $testLabel -body {evlRoute $mgr $pktArray }  -result $expectedResult 
       } else {
        puts "\tRunning $testId\t($testLabel)"
        test $testId $testLabel -body {evlRoute $mgr $pktArray}  -result $expectedResult
       }
    }
  }
}

### 


proc printTcpPkt { pkt } {
  puts "length:[pktReadLength $pkt];"
  puts "srcip:[pktReadSrcIp $pkt]; destip:[pktReadDestIp $pkt];"
  puts "srcport:[pktReadTcpSrcPort $pkt]; destport:[pktReadTcpDestPort $pkt];"
  puts "ack:[pktReadTcpAckNum $pkt]; seq:[pktReadTcpSeqNum $pkt];"
  puts "ipFlags:[pktReadIpFlags $pkt]"
  puts "ttl:[pktReadTtl $pkt]"
  puts "tcpflags:[pktReadTcpFlags $pkt]"
}

proc addPkt { mgr pkt } {
  set pktText "protocol:tcp; srcip:[pktReadDestIp $pkt]; destip:[pktReadSrcIp $pkt]; offset:0; ipflags:!MF; ipflags:!RB; ipflags:!DF; ttl:255; srcport:0; destport:1; tcpflags:!F; tcpflags:!S; tcpflags:!R; tcpflags:!P; tcpflags:!A; tcpflags:!U; tcpflags:!E; tcpflags:!C; ack:0; seq:1;"
  set newPkt [createPktFromText $pktText]

  evlMgrInsertPktIntoInputBuffer $mgr $newPkt
}

proc reactTest { } {
  set iBufSize 	  100000
  set oBufSize 	  100000
  set actionBufSize 100000
  
  set numIterations 1
  
  set ppCacheSize 100000
  
  set basicSlice 0.1
  set getPacketsWeight 1
  set computeActionsWeight 1
  set performActionsWeight 1
  set queuingWeight 1
  set writePacketsWeight 1
  
  set recordPktsWritten 1

  set pktArrayText {
  	{ protocol:tcp; srcip:0.0.0.0; destip:0.0.0.1; offset:0; ipflags:!MF; ipflags:!RB; ipflags:!DF; ttl:255; srcport:0; destport:1; tcpflags:!F; tcpflags:!S; tcpflags:!R; tcpflags:!P; tcpflags:!A; tcpflags:!U; tcpflags:!E; tcpflags:!C; ack:0; seq:1; }
  	{ protocol:tcp; srcip:1.1.1.1; destip:2.2.2.2; offset:0; ipflags:!MF; ipflags:!RB; ipflags:!DF; ttl:255; srcport:0; destport:1; tcpflags:!F; tcpflags:!S; tcpflags:!R; tcpflags:!P; tcpflags:!A; tcpflags:!U; tcpflags:!E; tcpflags:!C; ack:0; seq:1; }
 	}

  set mgrText { tcp any any -> any any ( ) tcl-ext:addPkt; }

  set pktArray [createPktArrayFromText $pktArrayText]
  set mgr [evlBuildManagerFromText $mgrText]

  set pkt [createPktFromText [lindex $pktArrayText 0 ]]
  # printTcpPkt $pkt
  evlRoute $mgr $pktArray
  for { set i 0 } { $i < 10000 } { incr i } {
    addPkt $mgr $pkt
  }
  puts "Done with reactTest"

}

proc ucodeTest { } {
  global pathToTestFiles
  set pktArrayText {
  	{ protocol:tcp; srcip:0.0.0.0; destip:0.0.0.1; size:20; content:adnan012345678901234; }
 	}

  set pktArray [createPktArrayFromText $pktArrayText]

  set rText {
    preprocess ip any any -> any any ( ) c-ext:Uc_BasicTest:"string passed to basic test";
  }

  set mgr [evlBuildManagerFromText $rText]
  evlMgrRegisterUcode $mgr "Uc_BasicTest" "$pathToTestFiles/libucode.so"
  evlRoute $mgr $pktArray
  puts "Done with ucodeTest"
}


proc pluginTest { } {
  set pktArrayText { {protocol:tcp; srcip:0.0.0.0; destip:0.0.0.1; srcport:0; destport:1; content:"get foo/bar\n space"; size:20;} }

  set mgrText 	{ 
  	tcp any any -> any any ( ) c-ext:stats:0.00001;
  	tcp any any -> any any ( ) c-ext:limit:1.0:1:limit test;
  	tcp any any -> any any ( ) c-ext:urls;
  }

  set pktArray [createPktArrayFromText $pktArrayText]

  set iBufSize 	  10000
  set oBufSize 	  10000
  set actionBufSize 10000
  
  set numIterations 1000000
  
  set ppCacheSize 1000000
  
  set mgr [evlBuildManagerFromText $mgrText]
  evlMgrRegisterUcode $mgr "stats" "./src/ucode/libucode.so"
  evlMgrRegisterUcode $mgr "limit" "./src/ucode/libucode.so"
  evlMgrRegisterUcode $mgr "urls" "./src/ucode/libucode.so"

  evlRoute $mgr $pktArray
  puts "Done with statsTest"
}



# here are the tests

qTest
reactTest
ucodeTest
pluginTest