Use proper clock mocking in the loopback example.

v0.7.x
whitequark 2017-07-23 06:08:13 +00:00
parent bdfc47d633
commit 6dd833f1f7
2 changed files with 67 additions and 12 deletions

View File

@ -23,9 +23,60 @@ use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface};
use smoltcp::socket::{AsSocket, SocketSet};
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
#[cfg(not(feature = "std"))]
mod mock {
use core::cell::Cell;
#[derive(Debug)]
pub struct Clock(Cell<u64>);
impl Clock {
pub fn new() -> Clock {
Clock(Cell::new(0))
}
pub fn advance(&mut self, millis: u64) {
self.0.set(self.0.get() + millis)
}
pub fn elapsed(&self) -> u64 {
self.0.get()
}
}
}
#[cfg(feature = "std")]
mod mock {
use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicUsize};
// should be AtomicU64 but that's unstable
#[derive(Debug, Clone)]
pub struct Clock(Arc<AtomicUsize>);
impl Clock {
pub fn new() -> Clock {
Clock(Arc::new(AtomicUsize::new(0)))
}
pub fn advance(&self, millis: u64) {
self.0.fetch_add(millis as usize, Ordering::SeqCst);
}
pub fn elapsed(&self) -> u64 {
self.0.load(Ordering::SeqCst) as u64
}
}
}
fn main() {
let clock = mock::Clock::new();
#[cfg(feature = "std")]
utils::setup_logging();
{
let clock = clock.clone();
utils::setup_logging_with_clock(move || clock.elapsed());
}
let mut device = Loopback::new();
#[cfg(feature = "std")]
@ -68,8 +119,7 @@ fn main() {
let mut did_listen = false;
let mut did_connect = false;
let mut done = false;
let mut timestamp_ms = 0;
while !done && timestamp_ms < 500 {
while !done && clock.elapsed() < 10_000 {
{
let socket: &mut TcpSocket = socket_set.get_mut(server_handle).as_socket();
if !socket.is_active() && !socket.is_listening() {
@ -102,14 +152,12 @@ fn main() {
}
}
match iface.poll(&mut socket_set, timestamp_ms) {
match iface.poll(&mut socket_set, clock.elapsed()) {
Ok(()) | Err(Error::Exhausted) => (),
Err(e) => debug!("poll error: {}", e)
}
const DELAY: u64 = 20;
debug!("{}ms pass", DELAY);
timestamp_ms += DELAY;
clock.advance(1);
}
if !done {

View File

@ -12,13 +12,12 @@ use smoltcp::phy::{Tracer, FaultInjector, TapInterface};
use smoltcp::wire::EthernetFrame;
use smoltcp::wire::PrettyPrinter;
pub fn setup_logging() {
let startup_time = Instant::now();
pub fn setup_logging_with_clock<F>(since_startup: F)
where F: Fn() -> u64 + Send + Sync + 'static {
LogBuilder::new()
.format(move |record: &LogRecord| {
let elapsed = Instant::now().duration_since(startup_time);
let timestamp = format!("[{:6}.{:03}s]",
elapsed.as_secs(), elapsed.subsec_nanos() / 1000000);
let elapsed = since_startup();
let timestamp = format!("[{:6}.{:03}s]", elapsed / 1000, elapsed % 1000);
if record.target().ends_with("::utils") {
let mut message = format!("{}", record.args());
message.pop();
@ -37,6 +36,14 @@ pub fn setup_logging() {
.unwrap();
}
pub fn setup_logging() {
let startup_at = Instant::now();
setup_logging_with_clock(move || {
let elapsed = Instant::now().duration_since(startup_at);
elapsed.as_secs() * 1000 + (elapsed.subsec_nanos() / 1000) as u64
})
}
pub fn trace_writer(printer: PrettyPrinter<EthernetFrame<&[u8]>>) {
trace!("{}", printer)
}