Skip to content

Commit

Permalink
Unit & Integration testing (#4)
Browse files Browse the repository at this point in the history
* add testing capabilties to workspace (unit and integration)

---------

Co-authored-by: jmwample <[email protected]>
Co-authored-by: Erik Chi <[email protected]>
  • Loading branch information
3 people authored Oct 22, 2023
1 parent 292930c commit bbe6daf
Show file tree
Hide file tree
Showing 41 changed files with 440 additions and 221 deletions.
30 changes: 27 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
run: cargo clippy --workspace --all-targets --verbose --all-features

build:
name: Test and Build
name: Test and Build WASM
needs: format
# needs: [format, lint]
strategy:
Expand All @@ -45,7 +45,31 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

# Build for WATER host
- name: Build WATER Host crate
run: cargo build
working-directory: crates/water

# install wasm32-wasi target
- name: Add wasm32-wasi target
run: rustup target add wasm32-wasi

# Build for wasm32-wasi target
- name: Build wasm32-wasi Target
run: |
for member in crates/wasm/ examples/water_bins/ss_client_wasm_v1/ examples/water_bins/echo_client/; do
cargo build --verbose --manifest-path $member/Cargo.toml --target wasm32-wasi
done
env:
RUSTFLAGS: --cfg tokio_unstable

- name: Test
run: cargo test --verbose --workspace --all-features
- name: Build
run: cargo build --verbose
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

[workspace]
members = ["crates/*", "examples/water_bins/*", "examples/clients/*"]
members = ["crates/*", "examples/water_bins/*", "examples/clients/*", "tests"]
# exclude = ["crates/foo", "path/to/other"]
default-members = ["crates/*"]
resolver="2"
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ nc 127.0.0.1 9005
```
you should see `> CONNECTED` in the terminal of running WASM, then you can connect a bunch like this and input anything to see how it echos.


## Running tests

```sh
# runs ALL tests
cargo test --workspace --verbose

# run tests for a single crate
cargo test -p <crate_name> --verbose

# run a single test (or test matching name prefix) in a single crate
cargo test -p <crate_name> --verbose -- <test_name>
```

## TODOs
- [ ] wasm_config sharing implementation
- [ ] Generalize Host export TCP listener helper function
Expand Down
5 changes: 5 additions & 0 deletions crates/wasm/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
target = "wasm32-wasi"

[target.wasm32-wasi]
rustflags = [ "--cfg", "tokio_unstable"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Dialer {
};

if fd < 0 {
return Err(anyhow!("failed to create listener"));
return Err(anyhow!("failed to connect to remote"));
}

Ok(fd)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
27 changes: 25 additions & 2 deletions crates/water/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub struct WATERConfig {
pub filepath: String,
pub entry_fn: String,
pub config_wasm: String,
pub client_type: u32,
pub client_type: WaterBinType,
pub debug: bool,
}

Expand All @@ -13,7 +13,7 @@ impl WATERConfig {
filepath: String,
entry_fn: String,
config_wasm: String,
client_type: u32,
client_type: WaterBinType,
debug: bool,
) -> Result<Self, anyhow::Error> {
Ok(WATERConfig {
Expand All @@ -25,3 +25,26 @@ impl WATERConfig {
})
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum WaterBinType {
Unknown,
Wrap,
Dial,
Listen,
Relay,
Runner,
}

impl From<u32> for WaterBinType {
fn from(num: u32) -> Self {
match num {
0 => WaterBinType::Dial,
1 => WaterBinType::Listen,
2 => WaterBinType::Runner,
3 => WaterBinType::Wrap,
4 => WaterBinType::Relay,
_ => WaterBinType::Unknown,
}
}
}
1 change: 1 addition & 0 deletions crates/water/src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub const WRITE_DONE_FN: &str = "_user_write_done";
pub const WATER_BRIDGING_FN: &str = "_set_inbound";
pub const READER_FN: &str = "_read";
pub const WRITER_FN: &str = "_write";
pub const DIAL_FN: &str = "_dial";

pub const RUNTIME_VERSION_MAJOR: i32 = 0x001aaaaa;
pub const RUNTIME_VERSION: &str = "v0.1-alpha";
8 changes: 8 additions & 0 deletions crates/water/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ pub mod errors;
pub mod globals;
pub mod runtime;
pub mod utils;

#[cfg(test)]
mod tests {
#[test]
fn water_runtime_test() {
assert_eq!(1, 1);
}
}
16 changes: 10 additions & 6 deletions crates/water/src/runtime/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,16 @@ impl H2O<Host> {
}
};

// open the config file and insert to WASM
let dir = Dir::open_ambient_dir(".", ambient_authority())?; // Open the root directory
let wasi_file = dir.open_with(
&config.config_wasm,
OpenOptions::new().read(true).write(true),
)?;
// Obtain the directory path and file name from config_wasm
let full_path = Path::new(&config.config_wasm);
let parent_dir = full_path.parent().unwrap(); // Assumes config_wasm has a parent directory
let file_name = full_path.file_name().unwrap().to_str().unwrap(); // Assumes file_name is valid UTF-8

// Open the parent directory
let dir = Dir::open_ambient_dir(parent_dir, ambient_authority())?;

let wasi_file = dir.open_with(file_name, OpenOptions::new().read(true).write(true))?;

let wasi_file = wasmtime_wasi::sync::file::File::from_cap_std(wasi_file);

let ctx = self.store.data_mut().preview1_ctx.as_mut().unwrap();
Expand Down
35 changes: 20 additions & 15 deletions crates/water/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod version_common;
use std::{
io::{Read, Write},
os::unix::io::{AsRawFd, FromRawFd},
path::Path,
sync::Arc,
};

Expand All @@ -32,8 +33,8 @@ use wasmtime_wasi_threads::WasiThreadsCtx;

// =================== CURRENT CRATE IMPORTS ===================
use crate::{
config::WATERConfig,
globals::{CONFIG_FN, INIT_FN, READER_FN, WATER_BRIDGING_FN, WRITER_FN},
config::{WATERConfig, WaterBinType},
globals::{CONFIG_FN, DIAL_FN, INIT_FN, READER_FN, WATER_BRIDGING_FN, WRITER_FN},
};

// =================== MODULES' DEPENDENCIES ===================
Expand Down Expand Up @@ -61,19 +62,23 @@ pub struct WATERClient {
impl WATERClient {
pub fn new(conf: WATERConfig) -> Result<Self, anyhow::Error> {
// client_type: 0 -> Dialer, 1 -> Listener, 2 -> Runner
let water: WATERClientType;
if conf.client_type == 0 {
let stream = WATERStream::init(&conf)?;
water = WATERClientType::Dialer(stream);
} else if conf.client_type == 1 {
let stream = WATERListener::init(&conf)?;
water = WATERClientType::Listener(stream);
} else if conf.client_type == 2 {
let runner = WATERRunner::init(&conf)?;
water = WATERClientType::Runner(runner);
} else {
return Err(anyhow::anyhow!("Invalid client type"));
}
let water = match conf.client_type {
WaterBinType::Dial => {
let stream = WATERStream::init(&conf)?;
WATERClientType::Dialer(stream)
}
WaterBinType::Listen => {
let stream = WATERListener::init(&conf)?;
WATERClientType::Listener(stream)
}
WaterBinType::Runner => {
let runner = WATERRunner::init(&conf)?;
WATERClientType::Runner(runner)
}
_ => {
return Err(anyhow::anyhow!("Invalid client type"));
}
};

Ok(WATERClient {
config: conf,
Expand Down
5 changes: 4 additions & 1 deletion crates/water/src/runtime/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ impl WATERRunner<Host> {
.core
.instance
.get_func(&mut self.core.store, &conf.entry_fn)
.unwrap();
.context(format!(
"failed to find declared entry function: {}",
&conf.entry_fn
))?;
match fnc.call(&mut self.core.store, &[], &mut []) {
Ok(_) => {}
Err(e) => return Err(anyhow::Error::msg(format!("run function failed: {}", e))),
Expand Down
13 changes: 7 additions & 6 deletions crates/water/src/runtime/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,7 @@ impl WATERStream<Host> {

// TODO: add addr:port sharing with WASM, for now WASM is using config.json's remote_addr:port
// let fnc = self.core.instance.get_func(&mut self.core.store, &conf.entry_fn).unwrap();
let fnc = match self
.core
.instance
.get_func(&mut self.core.store, &conf.entry_fn)
{
let fnc = match self.core.instance.get_func(&mut self.core.store, DIAL_FN) {
Some(func) => func,
None => {
return Err(anyhow::Error::msg(format!(
Expand Down Expand Up @@ -168,7 +164,12 @@ impl WATERStream<Host> {

std::mem::forget(water_io); // forget the water_io, so that it won't be closed

let ctx = core.store.data_mut().preview1_ctx.as_mut().unwrap();
let ctx = core
.store
.data_mut()
.preview1_ctx
.as_mut()
.context("Failed to retrieve preview1_ctx from Host")?;
let water_io_fd = ctx.push_file(Box::new(water_io_file), FileAccessMode::all())?;

let water_bridging = match core.instance.get_func(&mut core.store, WATER_BRIDGING_FN) {
Expand Down
2 changes: 1 addition & 1 deletion examples/clients/cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name="cli"
name="cli-dev"
version = "0.1.0"
authors.workspace = true
description.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions examples/clients/cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct Args {
#[arg(short, long, default_value_t = 2)]
type_client: u32,

/// Optional argument specifying the client_type, default to be Runner
/// Optional argument enabling debug logging
#[arg(short, long, default_value_t = false)]
debug: bool,
}
Expand All @@ -37,7 +37,7 @@ impl From<Args> for WATERConfig {
filepath: args.wasm_path,
entry_fn: args.entry_fn,
config_wasm: args.config_wasm,
client_type: args.type_client,
client_type: args.type_client.into(),
debug: args.debug,
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/water_bins/echo_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ url = { version = "2.2.2", features = ["serde"] }
libc = "0.2.147"

# water wasm lib import
water-wasm = { path = "../../../crates/water_wasm/", version = "0.1.0" }
water-wasm = { path = "../../../crates/wasm/", version = "0.1.0" }
Binary file modified examples/water_bins/echo_client/proxy.wasm
Binary file not shown.
4 changes: 4 additions & 0 deletions examples/water_bins/echo_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ use water_wasm::*;

pub mod async_socks5_listener;

// Export the version of this WASM module
#[export_name = "V1"]
pub static V1: i32 = 0;

// create a mutable global variable stores a pointer to the config
lazy_static! {
static ref DIALER: Mutex<Dialer> = Mutex::new(Dialer::new());
Expand Down
2 changes: 1 addition & 1 deletion examples/water_bins/ss_client_wasm_v1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ futures = "0.3.28"
pin-project = "1.1.2"

# water wasm lib import
water-wasm = { path = "../../../crates/water_wasm/", version = "0.1.0" }
water-wasm = { path = "../../../crates/wasm/", version = "0.1.0" }
Binary file modified examples/water_bins/ss_client_wasm_v1/ss_client_wasm.wasm
Binary file not shown.
23 changes: 23 additions & 0 deletions tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "tests"
version = "0.1.0"
authors.workspace = true
description.workspace = true
edition.workspace = true
publish = false


[dev-dependencies]
water-wasm = { path = "../crates/wasm" }
water = { path = "../crates/water" }

tracing = "0.1"
tracing-subscriber = "0.3.17"
rand = "0.8"
pprof = { version = "0.11.1", features = ["flamegraph", "protobuf-codec", "prost-codec"] }
anyhow = "1.0.7"
shadowsocks-service = {version = "1.17.0", features = ["server"]}
shadowsocks-rust = "1.17.0"
tokio = { version = "1.24.2", features = ["full", "macros"] }
futures = "0.3.28"
tempfile = "3.8.0"
Loading

0 comments on commit bbe6daf

Please sign in to comment.