about summary refs log tree commit diff
path: root/src/libstd/rt/io
diff options
context:
space:
mode:
authorEric Reed <ereed@mozilla.com>2013-06-25 11:43:40 -0700
committerEric Reed <ereed@mozilla.com>2013-06-25 11:43:40 -0700
commit794923c99511398bc90400e380dd11770ec8e614 (patch)
tree63a4ca6385e7f6074b95de6d0ee391463b5bff75 /src/libstd/rt/io
parent55dda46cf676e5efd713a0c1c8c4c5a297a6db02 (diff)
UDP networking with tests
Diffstat (limited to 'src/libstd/rt/io')
-rw-r--r--src/libstd/rt/io/net/udp.rs103
1 files changed, 99 insertions, 4 deletions
diff --git a/src/libstd/rt/io/net/udp.rs b/src/libstd/rt/io/net/udp.rs
index ac5a118f22a..97c09525d35 100644
--- a/src/libstd/rt/io/net/udp.rs
+++ b/src/libstd/rt/io/net/udp.rs
@@ -44,7 +44,6 @@ impl UdpSocket {
             Ok((nread, src)) => Some((nread, src)),
             Err(ioerr) => {
                 // EOF is indicated by returning None
-                // XXX do we ever find EOF reading UDP packets?
                 if ioerr.kind != EndOfFile {
                     read_error::cond.raise(ioerr);
                 }
@@ -86,10 +85,12 @@ impl UdpStream {
 
 impl Reader for UdpStream {
     fn read(&mut self, buf: &mut [u8]) -> Option<uint> { 
-        let conn = self.connectedTo;
         do self.as_socket |sock| {
-            sock.recvfrom(buf)
-                .map_consume(|(nread,src)| if src == conn {nread} else {0})
+            match sock.recvfrom(buf) {
+                Some((_nread, src)) if src != self.connectedTo => Some(0),
+                Some((nread, _src)) => Some(nread),
+                None => None,
+            }
         }
     }
 
@@ -105,3 +106,97 @@ impl Writer for UdpStream {
 
     fn flush(&mut self) { fail!() }
 }
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use rt::test::*;
+    use rt::io::net::ip::Ipv4;
+    use rt::io::*;
+    use option::{Some, None};
+
+    #[test]  #[ignore]
+    fn bind_error() {
+        do run_in_newsched_task {
+            let mut called = false;
+            do io_error::cond.trap(|e| {
+                assert!(e.kind == PermissionDenied);
+                called = true;
+            }).in {
+                let addr = Ipv4(0, 0, 0, 0, 1);
+                let socket = UdpSocket::bind(addr);
+                assert!(socket.is_none());
+            }
+            assert!(called);
+        }
+    }
+
+    #[test] 
+    fn socket_smoke_test() {
+        do run_in_newsched_task {
+            let server_ip = next_test_ip4();
+            let client_ip = next_test_ip4();
+
+            do spawntask_immediately {
+                match UdpSocket::bind(server_ip) {
+                    Some(server) => {
+                        let mut buf = [0];
+                        match server.recvfrom(buf) {
+                            Some((nread, src)) => {
+                                assert_eq!(nread, 1);
+                                assert_eq!(buf[0], 99);
+                                assert_eq!(src, client_ip);
+                            }
+                            None => fail!()
+                        }
+                    }
+                    None => fail!()
+                }
+            }
+
+            do spawntask_immediately {
+                match UdpSocket::bind(client_ip) {
+                    Some(client) => client.sendto([99], server_ip),
+                    None => fail!()
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn stream_smoke_test() {
+        do run_in_newsched_task {
+            let server_ip = next_test_ip4();
+            let client_ip = next_test_ip4();
+
+            do spawntask_immediately {
+                match UdpSocket::bind(server_ip) {
+                    Some(server) => {
+                        let server = ~server;
+                        let mut stream = server.connect(client_ip);
+                        let mut buf = [0];
+                        match stream.read(buf) {
+                            Some(nread) => {
+                                assert_eq!(nread, 1);
+                                assert_eq!(buf[0], 99);
+                            }
+                            None => fail!()
+                        }
+                    }
+                    None => fail!()
+                }
+            }
+
+            do spawntask_immediately {
+                match UdpSocket::bind(client_ip) {
+                    Some(client) => {
+                        let client = ~client;
+                        let mut stream = client.connect(server_ip);
+                        stream.write([99]);
+                    }
+                    None => fail!()
+                }
+            }
+        }
+    }
+}