Skip to content

Commit

Permalink
Test Framework Base (#1)
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Agia <chrisagia@google.com>
  • Loading branch information
agiachris authored Aug 12, 2020
1 parent ff0f9c2 commit 51ac990
Show file tree
Hide file tree
Showing 16 changed files with 3,287 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
14 changes: 14 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "proxy-wasm-test-framework"
version = "0.1.0"
authors = ["Christopher Agia <chrisagia@google.com>"]
edition = "2018"

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

[dependencies]
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "2482bd80c24a6b23ac1a259df77c61d5cc9c93a9" }
anyhow = "1.0.31"
lazy_static = "1.4.0"
more-asserts = "0.2.1"
rand = "0.7.3"
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
# WebAssembly for Proxies (test framework)

The Proxy-Wasm ABI and associated SDKs enable developers to build extensions in
any of the supported languages and deliver the plugins as WebAssembly modules at
run-time. This repository contains a standalone runner which serves as a test
harness and simulator for Proxy-Wasm extensions, enabling quick testing in a
controlled environment.

### Examples

The basic usage of this test-framework is provided in the examples/ folder which
contains mocking of proxy-wasm modules provided in the proxy-wasm-rust-sdk
examples/.

## Supported

- Low-level expectation setting over most host-side functions that are consumed
immediately
- Checking of residual low-level expectations after wasm-function call has
completed
- Various high-level (simulator defaults) expectations that persist across
several host-function calls as opposed to being immediately consumed
- Expectation setting over returns from functions exposed on the proxy-wasm
module

## In Progress

- Complete default implementation for all host-side functions
- Low-level expectation setting for the remaining host-side functions
- High-level expectation setting for the remaining host-side functions
- Integration test examples
26 changes: 26 additions & 0 deletions examples/abi_boundary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::Result;
use proxy_wasm_test_framework::utility;
use std::env;

fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
assert_eq!(args.len(), 2);

let proxy_wasm_module_path = &args[1];
utility::print_boundary(proxy_wasm_module_path)?;
return Ok(());
}
51 changes: 51 additions & 0 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::Result;
use proxy_wasm_test_framework::{tester, types::*};
use std::env;

fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
assert_eq!(args.len(), 2);
let hello_world_path = &args[1];
let mut hello_world_test = tester::test(hello_world_path)?;

hello_world_test
.call_start()
.execute_and_expect(ReturnType::None)?;

let root_context = 1;
hello_world_test
.call_proxy_on_context_create(root_context, 0)
.execute_and_expect(ReturnType::None)?;

hello_world_test
.call_proxy_on_vm_start(root_context, 0)
.expect_log(LogLevel::Info, "Hello, World!")
.expect_set_tick_period_millis(5 * 10u64.pow(3))
.execute_and_expect(ReturnType::Bool(true))?;

hello_world_test
.call_proxy_on_tick(root_context)
.expect_get_current_time_nanos()
.returning(0 * 10u64.pow(9))
.execute_and_expect(ReturnType::None)?;

hello_world_test
.call_proxy_on_tick(root_context)
.execute_and_expect(ReturnType::None)?;

return Ok(());
}
74 changes: 74 additions & 0 deletions examples/http_auth_random.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::Result;
use proxy_wasm_test_framework::{tester, types::*};
use std::env;

fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
assert_eq!(args.len(), 2);
let http_auth_random_path = &args[1];
let mut http_auth_random = tester::test(http_auth_random_path)?;

http_auth_random
.call_start()
.execute_and_expect(ReturnType::None)?;

let root_context = 1;
http_auth_random
.call_proxy_on_context_create(root_context, 0)
.execute_and_expect(ReturnType::None)?;

let http_context = 2;
http_auth_random
.call_proxy_on_context_create(http_context, root_context)
.execute_and_expect(ReturnType::None)?;

http_auth_random
.call_proxy_on_request_headers(http_context, 0)
.expect_http_call(
"httpbin",
vec![
(":method", "GET"),
(":path", "/bytes/1"),
(":authority", "httpbin.org"),
],
None,
vec![],
5 * 10u64.pow(3),
)
.returning(0)
.execute_and_expect(ReturnType::Action(Action::Pause))?;

let buffer_data = "custom_developer_body";
http_auth_random
.call_proxy_on_http_call_response(http_context, 0, 0, buffer_data.len() as i32, 0)
.expect_get_buffer_bytes(BufferType::HttpCallResponseBody)
.returning(buffer_data)
.expect_send_local_response(
403,
Some("Access forbidden.\n"),
vec![("Powered-By", "proxy-wasm")],
-1,
)
.execute_and_expect(ReturnType::None)?;

http_auth_random
.call_proxy_on_response_headers(http_context, 0)
.expect_replace_header_map_value(MapType::HttpResponseHeaders, "Powered-By", "proxy-wasm")
.execute_and_expect(ReturnType::Action(Action::Continue))?;

return Ok(());
}
71 changes: 71 additions & 0 deletions examples/http_headers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::Result;
use proxy_wasm_test_framework::{tester, types::*};
use std::env;

fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
assert_eq!(args.len(), 2);
let http_headers_path = &args[1];
let mut http_headers_test = tester::test(http_headers_path)?;

http_headers_test
.call_start()
.execute_and_expect(ReturnType::None)?;

let root_context = 1;
http_headers_test
.call_proxy_on_context_create(root_context, 0)
.execute_and_expect(ReturnType::None)?;

let http_context = 2;
http_headers_test
.call_proxy_on_context_create(http_context, root_context)
.execute_and_expect(ReturnType::None)?;

http_headers_test
.call_proxy_on_request_headers(http_context, 0)
.expect_get_header_map_pairs(MapType::HttpRequestHeaders)
.returning(vec![
(":method", "GET"),
(":path", "/hello"),
(":authority", "developer"),
])
.expect_get_header_map_value(MapType::HttpRequestHeaders, ":path")
.returning("/hello")
.expect_send_local_response(
200,
Some("Hello, World!\n"),
vec![("Hello", "World"), ("Powered-By", "proxy-wasm")],
-1,
)
.execute_and_expect(ReturnType::Action(Action::Pause))?;

http_headers_test
.call_proxy_on_response_headers(http_context, 0)
.expect_get_header_map_pairs(MapType::HttpResponseHeaders)
.returning(vec![(":status", "200"), ("Powered-By", "proxy-wasm")])
.expect_log(LogLevel::Trace, "#2 <- :status: 200")
.expect_log(LogLevel::Trace, "#2 <- Powered-By: proxy-wasm")
.execute_and_expect(ReturnType::Action(Action::Continue))?;

http_headers_test
.call_proxy_on_log(http_context)
.expect_log(LogLevel::Trace, "#2 completed.")
.execute_and_expect(ReturnType::None)?;

return Ok(());
}
Loading

0 comments on commit 51ac990

Please sign in to comment.