decoupling sockets from logic for tests

This commit is contained in:
Nikolay Volf 2016-02-03 03:55:18 +03:00
parent 60aa0d6799
commit 206cb6b227
2 changed files with 41 additions and 34 deletions

2
cov.sh
View File

@ -15,7 +15,7 @@ if ! type kcov > /dev/null; then
exit 1 exit 1
fi fi
cargo test -p ethcore --no-run || exit $? cargo test --features ethcore/json-tests -p ethcore --no-run || exit $?
mkdir -p target/coverage mkdir -p target/coverage
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1 --include-pattern src --verify target/coverage target/debug/deps/ethcore* kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1 --include-pattern src --verify target/coverage target/debug/deps/ethcore*
xdg-open target/coverage/index.html xdg-open target/coverage/index.html

View File

@ -6,7 +6,7 @@ use hash::*;
use sha3::*; use sha3::*;
use bytes::*; use bytes::*;
use rlp::*; use rlp::*;
use std::io::{self, Cursor, Read}; use std::io::{self, Cursor, Read, Write};
use error::*; use error::*;
use io::{IoContext, StreamToken}; use io::{IoContext, StreamToken};
use network::error::NetworkError; use network::error::NetworkError;
@ -22,12 +22,17 @@ use tiny_keccak::Keccak;
const ENCRYPTED_HEADER_LEN: usize = 32; const ENCRYPTED_HEADER_LEN: usize = 32;
const RECIEVE_PAYLOAD_TIMEOUT: u64 = 30000; const RECIEVE_PAYLOAD_TIMEOUT: u64 = 30000;
/// Low level tcp connection pub trait GenericSocket : Sized + Read + Write {
pub struct Connection { }
impl GenericSocket for TcpStream {
}
pub struct GenericConnection<Socket: GenericSocket> {
/// Connection id (token) /// Connection id (token)
pub token: StreamToken, pub token: StreamToken,
/// Network socket /// Network socket
pub socket: TcpStream, pub socket: Socket,
/// Receive buffer /// Receive buffer
rec_buf: Bytes, rec_buf: Bytes,
/// Expected size /// Expected size
@ -36,34 +41,11 @@ pub struct Connection {
send_queue: VecDeque<Cursor<Bytes>>, send_queue: VecDeque<Cursor<Bytes>>,
/// Event flags this connection expects /// Event flags this connection expects
interest: EventSet, interest: EventSet,
/// Shared network staistics /// Shared network statistics
stats: Arc<NetworkStats>, stats: Arc<NetworkStats>,
} }
/// Connection write status. impl<Socket: GenericSocket> GenericConnection<Socket> {
#[derive(PartialEq, Eq)]
pub enum WriteStatus {
/// Some data is still pending for current packet
Ongoing,
/// All data sent.
Complete
}
impl Connection {
/// Create a new connection with given id and socket.
pub fn new(token: StreamToken, socket: TcpStream, stats: Arc<NetworkStats>) -> Connection {
Connection {
token: token,
socket: socket,
send_queue: VecDeque::new(),
rec_buf: Bytes::new(),
rec_size: 0,
interest: EventSet::hup() | EventSet::readable(),
stats: stats,
}
}
/// Put a connection into read mode. Receiving up `size` bytes of data.
pub fn expect(&mut self, size: usize) { pub fn expect(&mut self, size: usize) {
if self.rec_size != self.rec_buf.len() { if self.rec_size != self.rec_buf.len() {
warn!(target:"net", "Unexpected connection read start"); warn!(target:"net", "Unexpected connection read start");
@ -79,7 +61,7 @@ impl Connection {
} }
let max = self.rec_size - self.rec_buf.len(); let max = self.rec_size - self.rec_buf.len();
// resolve "multiple applicable items in scope [E0034]" error // resolve "multiple applicable items in scope [E0034]" error
let sock_ref = <TcpStream as Read>::by_ref(&mut self.socket); let sock_ref = <Socket as Read>::by_ref(&mut self.socket);
match sock_ref.take(max as u64).try_read_buf(&mut self.rec_buf) { match sock_ref.take(max as u64).try_read_buf(&mut self.rec_buf) {
Ok(Some(size)) if size != 0 => { Ok(Some(size)) if size != 0 => {
self.stats.inc_recv(size); self.stats.inc_recv(size);
@ -142,6 +124,24 @@ impl Connection {
Ok(r) Ok(r)
}) })
} }
}
/// Low level tcp connection
pub type Connection = GenericConnection<TcpStream>;
impl Connection {
/// Create a new connection with given id and socket.
pub fn new(token: StreamToken, socket: TcpStream, stats: Arc<NetworkStats>) -> Connection {
Connection {
token: token,
socket: socket,
send_queue: VecDeque::new(),
rec_buf: Bytes::new(),
rec_size: 0,
interest: EventSet::hup() | EventSet::readable(),
stats: stats,
}
}
/// Register this connection with the IO event loop. /// Register this connection with the IO event loop.
pub fn register_socket<Host: Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> io::Result<()> { pub fn register_socket<Host: Handler>(&self, reg: Token, event_loop: &mut EventLoop<Host>) -> io::Result<()> {
@ -169,6 +169,15 @@ impl Connection {
} }
} }
/// Connection write status.
#[derive(PartialEq, Eq)]
pub enum WriteStatus {
/// Some data is still pending for current packet
Ongoing,
/// All data sent.
Complete
}
/// RLPx packet /// RLPx packet
pub struct Packet { pub struct Packet {
pub protocol: u16, pub protocol: u16,
@ -417,5 +426,3 @@ pub fn test_encryption() {
encoder.reset(); encoder.reset();
assert_eq!(got, after2); assert_eq!(got, after2);
} }