Begining of some test cases.
[crypto_lab1.git] / src / end_point.rs
index 9488d13..77af33d 100644 (file)
@@ -1,8 +1,10 @@
-use std::io::{ Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
+use std::io::{ MemWriter, Acceptor, Listener, TcpStream, IoResult, IoError, EndOfFile };
 use std::io::net::tcp::{ TcpAcceptor, TcpListener };
 use packet;
 use packet::{ Packet, Command, Answer, Error, ReadingResult, PacketType };
 
+static DEFAULT_TIMEOUT: Option<u64> = Some(500); // [ms].
+
 pub struct Server {
    acceptor: TcpAcceptor
 }
@@ -17,8 +19,8 @@ struct EndPoint {
 }
 
 impl Server {
-   pub fn new(port: u16) -> IoResult<Server> {
-      let mut acceptor = try!(TcpListener::bind("127.0.0.1", port).listen());
+   pub fn new(interface: &str, port: u16) -> IoResult<Server> {
+      let mut acceptor = try!(TcpListener::bind(interface, port).listen());
       
       let server = Server { 
          acceptor: acceptor.clone()
@@ -49,7 +51,7 @@ impl Server {
          match end_point.read() {         
             Ok(packet@Packet { t: Command(..), .. }) => {
                println!("[Server] Valid command received: {}", packet);
-               let answer = Answer(Packet::random_packet_data());
+               let answer = Answer(Packet::random_packet_data([]));
                match end_point.send(answer.clone()) {
                   Ok(_) =>
                      println!("[Server] Answer sent: {}", answer),
@@ -100,6 +102,71 @@ impl Client {
             println!("[Client] Cannot send this type of packet: {}", other)
       }
    }
+   
+   /// Send some valid and not-valid packets to the server and check the result.
+   pub fn start_tests(address: &str, port: u16) {
+      let execute = |f: &mut |&mut Client| -> bool| -> bool {
+         match Client::new(address, port) {
+            Ok(ref mut client) => (*f)(client),
+            Err(e) => {
+               println!("Unable to create a client. Error: {}", e);
+               false
+            }
+         }
+      };
+   
+      let mut tests = vec!(
+         |client: &mut Client| -> bool {
+            println!("Send a valid packet...");
+            match client.end_point.send_with_result(Command(Packet::random_packet_data([42]))) {
+               Ok(Ok(packet@Packet { t: Answer(..), .. })) =>
+                  true,
+               other => {
+                  println!("Error: {}", other);
+                  false
+               }
+            }
+         },
+         
+         |client: &mut Client| -> bool {
+            println!("Send a packet with an unknown type...");
+            client.end_point.current_timestamp += 1;
+            let mut m = MemWriter::new(); 
+            match (Packet { t: Command(Packet::random_packet_data([42])), timestamp: client.end_point.current_timestamp }).write(&mut m) {
+               Err(e) => {
+                  println!("Error: {}", e)
+                  false
+               },
+               _ => {
+                  let mut raw_packet = m.unwrap();
+                  raw_packet[2] = 0xEE; // Alter the type.
+                        
+                  match client.end_point.send_raw_with_result(raw_packet.as_slice()) {
+                     Ok(Err(packet::IOReadError( IoError { kind: TimedOut, .. }))) => true, // The server should not send a packet.
+                     other => {
+                        println!("Error: {}", other);
+                        false
+                     }
+                  }                  
+               }
+            }
+         }
+      );
+      
+      for (i, test) in range(0, tests.len()).zip(tests.iter_mut()) {
+         println!("===== Test case #{}:", i)
+         if execute(test) {
+            println!("===== Test passed");
+         } else {
+            println!("===== Test failed");
+            break;
+         }
+      }     
+      
+      // Send a packet with a wrong timestamp.
+      // Send a packet with a maximum timestamp.
+      // Send a packet with altered encrypted data.
+   }
 }
 
 impl EndPoint {   
@@ -109,9 +176,7 @@ impl EndPoint {
       Ok(())
    }
    
-   /**
-     * Send a packet and wait synchronously an answer.
-     */ 
+   /// Send a packet and wait for an answer synchronously.
    fn send_with_result(&mut self, p: PacketType) -> IoResult<ReadingResult> {
       match self.send(p) {
          Err(e) => Err(e),
@@ -119,11 +184,22 @@ impl EndPoint {
       }
    }
    
+   /// Send arbitrary data and wait for an answer synchronously.
+   /// Do not increment the current timestamp.
+   fn send_raw_with_result(&mut self, p: &[u8]) -> IoResult<ReadingResult> {
+      self.socket.set_timeout(DEFAULT_TIMEOUT);
+      match self.socket.write(p) {
+         Err(e) => Err(e),
+         _ => Ok(self.read())
+      }
+   }
+   
    fn send(&mut self, p: PacketType) -> IoResult<()> {
+      self.socket.set_timeout(DEFAULT_TIMEOUT);
       self.current_timestamp += 1;
       match (Packet { t: p, timestamp: self.current_timestamp }).write(&mut self.socket) {
-         Ok(_) => Ok(()),
-         Err(packet::WriteIOError(e)) => Err(e)
+         Err(packet::WriteIOError(e)) => Err(e),
+         _ => Ok(())
       }
    }
    
@@ -135,11 +211,12 @@ impl EndPoint {
          };
       };
    
+      self.socket.set_timeout(DEFAULT_TIMEOUT);      
       match Packet::read(&mut self.socket) {
          Ok(packet) => {
             if packet.timestamp <= self.current_timestamp {
                println!("Error, timestamp mismatch, current timestamp: {}, packet received: {}", self.current_timestamp, packet);
-               Err(packet::InvalidTimestamp)
+               Err(packet::InvalidTimestampError)
             } else {
                self.current_timestamp = packet.timestamp + 1;
                Ok(packet)
@@ -157,4 +234,4 @@ impl EndPoint {
             other
       }
    }
-}
\ No newline at end of file
+}