Skip to content

Commit

Permalink
introduce test utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
czarte committed Oct 15, 2024
1 parent c3e36f2 commit 129ec37
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 2 deletions.
2 changes: 1 addition & 1 deletion ip_country/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ workspace = "../node"
csv = "1.3.0"
itertools = "0.13.0"
lazy_static = "1.4.0"

test_utilities = { path = "../test_utilities"}

[[bin]]
name = "ip_country"
Expand Down
2 changes: 1 addition & 1 deletion ip_country/src/ip_country.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ fn write_value(
#[cfg(test)]
mod tests {
use super::*;
use masq_lib::test_utils::fake_stream_holder::{ByteArrayReader, ByteArrayWriter};
use std::io::{Error, ErrorKind};
use test_utilities::fake_stream_holder::{ByteArrayReader, ByteArrayWriter};

static PROPER_TEST_DATA: &str = "0.0.0.0,0.255.255.255,ZZ
1.0.0.0,1.0.0.255,AU
Expand Down
5 changes: 5 additions & 0 deletions node/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions test_utilities/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "test_utilities"
version = "0.1.0"
edition = "2021"
authors = ["Dan Wiebe <[email protected]>", "MASQ"]
license = "GPL-3.0-only"
description = "Testing utilities Code common to Node and masq; also, temporarily, to dns_utility"
workspace = "../node"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
154 changes: 154 additions & 0 deletions test_utilities/src/fake_stream_holder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved.

use std::cmp::min;
use std::io;
use std::io::Read;
use std::io::Write;
use std::io::{BufRead, Error};
use std::sync::{Arc, Mutex};

pub struct ByteArrayWriter {
inner_arc: Arc<Mutex<ByteArrayWriterInner>>,
}

pub struct ByteArrayWriterInner {
byte_array: Vec<u8>,
next_error: Option<Error>,
}

impl ByteArrayWriterInner {
pub fn get_bytes(&self) -> Vec<u8> {
self.byte_array.clone()
}
pub fn get_string(&self) -> String {
String::from_utf8(self.get_bytes()).unwrap()
}
}

impl Default for ByteArrayWriter {
fn default() -> Self {
ByteArrayWriter {
inner_arc: Arc::new(Mutex::new(ByteArrayWriterInner {
byte_array: vec![],
next_error: None,
})),
}
}
}

impl ByteArrayWriter {
pub fn new() -> ByteArrayWriter {
Self::default()
}

pub fn inner_arc(&self) -> Arc<Mutex<ByteArrayWriterInner>> {
self.inner_arc.clone()
}

pub fn get_bytes(&self) -> Vec<u8> {
self.inner_arc.lock().unwrap().byte_array.clone()
}
pub fn get_string(&self) -> String {
String::from_utf8(self.get_bytes()).unwrap()
}

pub fn reject_next_write(&mut self, error: Error) {
self.inner_arc().lock().unwrap().next_error = Some(error);
}
}

impl Write for ByteArrayWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let mut inner = self.inner_arc.lock().unwrap();
if let Some(next_error) = inner.next_error.take() {
Err(next_error)
} else {
for byte in buf {
inner.byte_array.push(*byte)
}
Ok(buf.len())
}
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

pub struct ByteArrayReader {
byte_array: Vec<u8>,
position: usize,
next_error: Option<Error>,
}

impl ByteArrayReader {
pub fn new(byte_array: &[u8]) -> ByteArrayReader {
ByteArrayReader {
byte_array: byte_array.to_vec(),
position: 0,
next_error: None,
}
}

pub fn reject_next_read(mut self, error: Error) -> ByteArrayReader {
self.next_error = Some(error);
self
}
}

impl Read for ByteArrayReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.next_error.take() {
Some(error) => Err(error),
None => {
let to_copy = min(buf.len(), self.byte_array.len() - self.position);
#[allow(clippy::needless_range_loop)]
for idx in 0..to_copy {
buf[idx] = self.byte_array[self.position + idx]
}
self.position += to_copy;
Ok(to_copy)
}
}
}
}

impl BufRead for ByteArrayReader {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
match self.next_error.take() {
Some(error) => Err(error),
None => Ok(&self.byte_array[self.position..]),
}
}

fn consume(&mut self, amt: usize) {
let result = self.position + amt;
self.position = if result < self.byte_array.len() {
result
} else {
self.byte_array.len()
}
}
}

pub struct FakeStreamHolder {
pub stdin: ByteArrayReader,
pub stdout: ByteArrayWriter,
pub stderr: ByteArrayWriter,
}

impl Default for FakeStreamHolder {
fn default() -> Self {
FakeStreamHolder {
stdin: ByteArrayReader::new(&[0; 0]),
stdout: ByteArrayWriter::new(),
stderr: ByteArrayWriter::new(),
}
}
}

impl FakeStreamHolder {
pub fn new() -> FakeStreamHolder {
Self::default()
}
}
3 changes: 3 additions & 0 deletions test_utilities/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Copyright (c) 2024, MASQ (https://masq.ai) and/or its affiliates. All rights reserved.

pub mod fake_stream_holder;

0 comments on commit 129ec37

Please sign in to comment.