| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 //! Tests all functionality in the system package | |
| 6 //! | |
| 7 //! Test failure is defined as the function returning via panicking | |
| 8 //! and the result being caught in the test! macro. If a test function | |
| 9 //! returns without panicking, it is assumed to pass. | |
| 10 | |
| 11 #[macro_use] | |
| 12 extern crate mojo; | |
| 13 | |
| 14 #[macro_use] | |
| 15 mod util; | |
| 16 | |
| 17 use mojo::system; | |
| 18 use mojo::system::{CastHandle, Handle}; | |
| 19 use mojo::system::core; | |
| 20 use mojo::system::data_pipe; | |
| 21 use mojo::system::message_pipe; | |
| 22 use mojo::system::shared_buffer; | |
| 23 use mojo::system::wait_set; | |
| 24 | |
| 25 use std::string::String; | |
| 26 use std::thread; | |
| 27 use std::vec::Vec; | |
| 28 | |
| 29 tests! { | |
| 30 fn get_time_ticks_now() { | |
| 31 let x = core::get_time_ticks_now(); | |
| 32 assert!(x >= 10); | |
| 33 } | |
| 34 | |
| 35 fn handle() { | |
| 36 let sb = shared_buffer::create(sbflags!(Create::None), 1).unwrap(); | |
| 37 let handle = sb.as_untyped(); | |
| 38 unsafe { | |
| 39 assert_eq!((handle.get_native_handle() != 0), handle.is_valid()); | |
| 40 assert!(handle.get_native_handle() != 0 && handle.is_valid()); | |
| 41 let mut h2 = system::acquire(handle.get_native_handle()); | |
| 42 assert!(h2.is_valid()); | |
| 43 h2.invalidate(); | |
| 44 assert!(!h2.is_valid()); | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 fn shared_buffer() { | |
| 49 let bufsize = 100; | |
| 50 let sb1; | |
| 51 { | |
| 52 let mut buf; | |
| 53 { | |
| 54 let sb_c = shared_buffer::create(sbflags!(Create::None), bufsize
).unwrap(); | |
| 55 // Extract original handle to check against | |
| 56 let sb_h = sb_c.get_native_handle(); | |
| 57 // Test casting of handle types | |
| 58 let sb_u = sb_c.as_untyped(); | |
| 59 assert_eq!(sb_u.get_native_handle(), sb_h); | |
| 60 let sb = unsafe { shared_buffer::SharedBuffer::from_untyped(sb_u
) }; | |
| 61 assert_eq!(sb.get_native_handle(), sb_h); | |
| 62 // Test map | |
| 63 buf = sb.map(0, bufsize, sbflags!(Map::None)).unwrap(); | |
| 64 assert_eq!(buf.len(), bufsize as usize); | |
| 65 // Test get info | |
| 66 let (flags, size) = sb.get_info().unwrap(); | |
| 67 assert_eq!(flags, sbflags!(Info::None)); | |
| 68 assert_eq!(size, bufsize); | |
| 69 buf.write(50, 34); | |
| 70 // Test duplicate | |
| 71 sb1 = sb.duplicate(sbflags!(Duplicate::None)).unwrap(); | |
| 72 } | |
| 73 // sb gets closed | |
| 74 buf.write(51, 35); | |
| 75 } | |
| 76 // buf just got closed | |
| 77 // remap to buf1 from sb1 | |
| 78 let buf1 = sb1.map(50, 50, sbflags!(Map::None)).unwrap(); | |
| 79 assert_eq!(buf1.len(), 50); | |
| 80 // verify buffer contents | |
| 81 assert_eq!(buf1.read(0), 34); | |
| 82 assert_eq!(buf1.read(1), 35); | |
| 83 } | |
| 84 | |
| 85 fn message_pipe() { | |
| 86 let (endpt, endpt1) = message_pipe::create(mpflags!(Create::None)).unwra
p(); | |
| 87 // Extract original handle to check against | |
| 88 let endpt_h = endpt.get_native_handle(); | |
| 89 // Test casting of handle types | |
| 90 let endpt_u = endpt.as_untyped(); | |
| 91 assert_eq!(endpt_u.get_native_handle(), endpt_h); | |
| 92 { | |
| 93 let endpt0 = unsafe { message_pipe::MessageEndpoint::from_untyped(en
dpt_u) }; | |
| 94 assert_eq!(endpt0.get_native_handle(), endpt_h); | |
| 95 { | |
| 96 let (s, r) = endpt0.wait(signals!(Signals::Readable), 0); | |
| 97 assert_eq!(r, mojo::MojoResult::DeadlineExceeded); | |
| 98 assert!(s.satisfied().is_writable()); | |
| 99 assert!(s.satisfiable().is_readable()); | |
| 100 assert!(s.satisfiable().is_writable()); | |
| 101 assert!(s.satisfiable().is_peer_closed()); | |
| 102 } | |
| 103 { | |
| 104 let (s, r) = endpt0.wait(signals!(Signals::Writable), system::MO
JO_INDEFINITE); | |
| 105 assert_eq!(r, mojo::MojoResult::Okay); | |
| 106 assert!(s.satisfied().is_writable()); | |
| 107 assert!(s.satisfiable().is_readable()); | |
| 108 assert!(s.satisfiable().is_writable()); | |
| 109 assert!(s.satisfiable().is_peer_closed()); | |
| 110 } | |
| 111 match endpt0.read(mpflags!(Read::None)) { | |
| 112 Ok((_msg, _handles)) => panic!("Read should not have succeeded."
), | |
| 113 Err(r) => assert_eq!(r, mojo::MojoResult::ShouldWait), | |
| 114 } | |
| 115 let hello = "hello".to_string().into_bytes(); | |
| 116 let write_result = endpt1.write(&hello, Vec::new(), mpflags!(Write::
None)); | |
| 117 assert_eq!(write_result, mojo::MojoResult::Okay); | |
| 118 { | |
| 119 let (s, r) = endpt0.wait(signals!(Signals::Readable), system::MO
JO_INDEFINITE); | |
| 120 assert_eq!(r, mojo::MojoResult::Okay); | |
| 121 assert!(s.satisfied().is_readable(), s.satisfied().is_writable()
); | |
| 122 assert!(s.satisfiable().is_readable()); | |
| 123 assert!(s.satisfiable().is_writable()); | |
| 124 assert!(s.satisfiable().is_peer_closed()); | |
| 125 } | |
| 126 let hello_data; | |
| 127 match endpt0.read(mpflags!(Read::None)) { | |
| 128 Ok((msg, _handles)) => hello_data = msg, | |
| 129 Err(r) => panic!("Failed to read message on endpt0, error: {}",
r), | |
| 130 } | |
| 131 assert_eq!(String::from_utf8(hello_data).unwrap(), "hello".to_string
()); | |
| 132 { | |
| 133 let handles: Vec<&Handle> = vec![&endpt0]; | |
| 134 let signals: Vec<system::HandleSignals> = vec![signals!(Signals:
:Readable)]; | |
| 135 let mut states: Vec<system::SignalsState> = vec![Default::defaul
t()]; | |
| 136 let (idx, r) = core::wait_many(&handles, &signals, &mut states,
10); | |
| 137 assert_eq!(r, mojo::MojoResult::DeadlineExceeded); | |
| 138 assert_eq!(idx, -1); | |
| 139 assert_eq!(states.len(), 1); | |
| 140 assert!(states[0].satisfied().is_writable()); | |
| 141 assert!(states[0].satisfiable().is_readable()); | |
| 142 assert!(states[0].satisfiable().is_writable()); | |
| 143 assert!(states[0].satisfiable().is_peer_closed()); | |
| 144 } | |
| 145 } | |
| 146 let (s, r) = endpt1.wait(signals!(Signals::Readable, Signals::Writable), | |
| 147 system::MOJO_INDEFINITE); | |
| 148 assert_eq!(r, mojo::MojoResult::FailedPrecondition); | |
| 149 assert!(s.satisfied().is_peer_closed()); | |
| 150 assert_eq!(s.satisfiable().get_bits(), system::Signals::PeerClosed as u3
2); | |
| 151 } | |
| 152 | |
| 153 fn data_pipe() { | |
| 154 let (cons0, prod0) = data_pipe::create_default().unwrap(); | |
| 155 // Extract original handle to check against | |
| 156 let cons_h = cons0.get_native_handle(); | |
| 157 let prod_h = prod0.get_native_handle(); | |
| 158 // Test casting of handle types | |
| 159 let cons_u = cons0.as_untyped(); | |
| 160 let prod_u = prod0.as_untyped(); | |
| 161 assert_eq!(cons_u.get_native_handle(), cons_h); | |
| 162 assert_eq!(prod_u.get_native_handle(), prod_h); | |
| 163 let cons = unsafe { data_pipe::Consumer::<u8>::from_untyped(cons_u) }; | |
| 164 let prod = unsafe { data_pipe::Producer::<u8>::from_untyped(prod_u) }; | |
| 165 assert_eq!(cons.get_native_handle(), cons_h); | |
| 166 assert_eq!(prod.get_native_handle(), prod_h); | |
| 167 // Test waiting on consumer | |
| 168 { | |
| 169 let (_s, r) = cons.wait(signals!(Signals::Readable), 0); | |
| 170 assert_eq!(r, mojo::MojoResult::DeadlineExceeded); | |
| 171 } | |
| 172 // Test waiting on producer | |
| 173 { | |
| 174 let (_s, r) = prod.wait(signals!(Signals::Writable), system::MOJO_IN
DEFINITE); | |
| 175 assert_eq!(r, mojo::MojoResult::Okay); | |
| 176 } | |
| 177 // Test one-phase read/write. | |
| 178 // Writing. | |
| 179 let hello = "hello".to_string().into_bytes(); | |
| 180 let bytes_written = prod.write(&hello, dpflags!(Write::None)).unwrap(); | |
| 181 assert_eq!(bytes_written, hello.len()); | |
| 182 // Reading. | |
| 183 { | |
| 184 let (_s, r) = cons.wait(signals!(Signals::Readable), system::MOJO_IN
DEFINITE); | |
| 185 assert_eq!(r, mojo::MojoResult::Okay); | |
| 186 } | |
| 187 let data_string = String::from_utf8(cons.read(dpflags!(Read::None)).unwr
ap()).unwrap(); | |
| 188 assert_eq!(data_string, "hello".to_string()); | |
| 189 { | |
| 190 // Test two-phase read/write. | |
| 191 // Writing. | |
| 192 let goodbye = "goodbye".to_string().into_bytes(); | |
| 193 let mut write_buf = match prod.begin(dpflags!(Write::None)) { | |
| 194 Ok(buf) => buf, | |
| 195 Err(err) => panic!("Error on write begin: {}", err), | |
| 196 }; | |
| 197 assert!(write_buf.len() >= goodbye.len()); | |
| 198 for i in 0..goodbye.len() { | |
| 199 write_buf[i] = goodbye[i]; | |
| 200 } | |
| 201 { | |
| 202 let (_s, r) = cons.wait(signals!(Signals::Readable), 0); | |
| 203 assert_eq!(r, mojo::MojoResult::DeadlineExceeded); | |
| 204 } | |
| 205 match write_buf.commit(goodbye.len()) { | |
| 206 Some((_buf, _err)) => assert!(false), | |
| 207 None => (), | |
| 208 } | |
| 209 // Reading. | |
| 210 { | |
| 211 let (_s, r) = cons.wait(signals!(Signals::Readable), system::MOJ
O_INDEFINITE); | |
| 212 assert_eq!(r, mojo::MojoResult::Okay); | |
| 213 } | |
| 214 let mut data_goodbye: Vec<u8> = Vec::with_capacity(goodbye.len()); | |
| 215 { | |
| 216 let read_buf = match cons.begin(dpflags!(Read::None)) { | |
| 217 Ok(buf) => buf, | |
| 218 Err(err) => panic!("Error on read begin: {}", err), | |
| 219 }; | |
| 220 for i in 0..read_buf.len() { | |
| 221 data_goodbye.push(read_buf[i]); | |
| 222 } | |
| 223 match cons.read(dpflags!(Read::None)) { | |
| 224 Ok(_bytes) => assert!(false), | |
| 225 Err(r) => assert_eq!(r, mojo::MojoResult::Busy), | |
| 226 } | |
| 227 match read_buf.commit(data_goodbye.len()) { | |
| 228 Some((_buf, _err)) => assert!(false), | |
| 229 None => (), | |
| 230 } | |
| 231 } | |
| 232 assert_eq!(data_goodbye.len(), goodbye.len()); | |
| 233 assert_eq!(String::from_utf8(data_goodbye).unwrap(), "goodbye".to_st
ring()); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 fn wait_set() { | |
| 238 let set0 = wait_set::WaitSet::new(wsflags!(Create::None)).unwrap(); | |
| 239 let set_h = set0.get_native_handle(); | |
| 240 let set_u = set0.as_untyped(); | |
| 241 assert_eq!(set_u.get_native_handle(), set_h); | |
| 242 let mut set = unsafe { wait_set::WaitSet::from_untyped(set_u) }; | |
| 243 let (endpt0, endpt1) = message_pipe::create(mpflags!(Create::None)).unwr
ap(); | |
| 244 let signals = signals!(Signals::Readable); | |
| 245 let flags = wsflags!(Add::None); | |
| 246 assert_eq!(set.add(&endpt0, signals, 245, flags), mojo::MojoResult::Okay
); | |
| 247 assert_eq!(set.add(&endpt0, signals, 245, flags), mojo::MojoResult::Alre
adyExists); | |
| 248 assert_eq!(set.remove(245), mojo::MojoResult::Okay); | |
| 249 assert_eq!(set.remove(245), mojo::MojoResult::NotFound); | |
| 250 assert_eq!(set.add(&endpt0, signals, 123, flags), mojo::MojoResult::Okay
); | |
| 251 thread::spawn(move || { | |
| 252 let hello = "hello".to_string().into_bytes(); | |
| 253 let write_result = endpt1.write(&hello, Vec::new(), mpflags!(Write::
None)); | |
| 254 assert_eq!(write_result, mojo::MojoResult::Okay); | |
| 255 }); | |
| 256 let mut output = Vec::with_capacity(1); | |
| 257 let max = set.wait_on_set(system::MOJO_INDEFINITE, &mut output).unwrap()
; | |
| 258 assert_eq!(output.len(), 1); | |
| 259 assert_eq!(output[0].cookie(), 123); | |
| 260 assert_eq!(output[0].result(), mojo::MojoResult::Okay); | |
| 261 assert!(output[0].state().satisfied().is_readable()); | |
| 262 assert_eq!(max, 1); | |
| 263 } | |
| 264 } | |
| OLD | NEW |