Skip to content

Commit 51ac990

Browse files
authored
Test Framework Base (#1)
Signed-off-by: Christopher Agia <[email protected]>
1 parent ff0f9c2 commit 51ac990

16 files changed

+3287
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "proxy-wasm-test-framework"
3+
version = "0.1.0"
4+
authors = ["Christopher Agia <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "2482bd80c24a6b23ac1a259df77c61d5cc9c93a9" }
11+
anyhow = "1.0.31"
12+
lazy_static = "1.4.0"
13+
more-asserts = "0.2.1"
14+
rand = "0.7.3"

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,31 @@
11
# WebAssembly for Proxies (test framework)
2+
3+
The Proxy-Wasm ABI and associated SDKs enable developers to build extensions in
4+
any of the supported languages and deliver the plugins as WebAssembly modules at
5+
run-time. This repository contains a standalone runner which serves as a test
6+
harness and simulator for Proxy-Wasm extensions, enabling quick testing in a
7+
controlled environment.
8+
9+
### Examples
10+
11+
The basic usage of this test-framework is provided in the examples/ folder which
12+
contains mocking of proxy-wasm modules provided in the proxy-wasm-rust-sdk
13+
examples/.
14+
15+
## Supported
16+
17+
- Low-level expectation setting over most host-side functions that are consumed
18+
immediately
19+
- Checking of residual low-level expectations after wasm-function call has
20+
completed
21+
- Various high-level (simulator defaults) expectations that persist across
22+
several host-function calls as opposed to being immediately consumed
23+
- Expectation setting over returns from functions exposed on the proxy-wasm
24+
module
25+
26+
## In Progress
27+
28+
- Complete default implementation for all host-side functions
29+
- Low-level expectation setting for the remaining host-side functions
30+
- High-level expectation setting for the remaining host-side functions
31+
- Integration test examples

examples/abi_boundary.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use anyhow::Result;
16+
use proxy_wasm_test_framework::utility;
17+
use std::env;
18+
19+
fn main() -> Result<()> {
20+
let args: Vec<String> = env::args().collect();
21+
assert_eq!(args.len(), 2);
22+
23+
let proxy_wasm_module_path = &args[1];
24+
utility::print_boundary(proxy_wasm_module_path)?;
25+
return Ok(());
26+
}

examples/hello_world.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use anyhow::Result;
16+
use proxy_wasm_test_framework::{tester, types::*};
17+
use std::env;
18+
19+
fn main() -> Result<()> {
20+
let args: Vec<String> = env::args().collect();
21+
assert_eq!(args.len(), 2);
22+
let hello_world_path = &args[1];
23+
let mut hello_world_test = tester::test(hello_world_path)?;
24+
25+
hello_world_test
26+
.call_start()
27+
.execute_and_expect(ReturnType::None)?;
28+
29+
let root_context = 1;
30+
hello_world_test
31+
.call_proxy_on_context_create(root_context, 0)
32+
.execute_and_expect(ReturnType::None)?;
33+
34+
hello_world_test
35+
.call_proxy_on_vm_start(root_context, 0)
36+
.expect_log(LogLevel::Info, "Hello, World!")
37+
.expect_set_tick_period_millis(5 * 10u64.pow(3))
38+
.execute_and_expect(ReturnType::Bool(true))?;
39+
40+
hello_world_test
41+
.call_proxy_on_tick(root_context)
42+
.expect_get_current_time_nanos()
43+
.returning(0 * 10u64.pow(9))
44+
.execute_and_expect(ReturnType::None)?;
45+
46+
hello_world_test
47+
.call_proxy_on_tick(root_context)
48+
.execute_and_expect(ReturnType::None)?;
49+
50+
return Ok(());
51+
}

examples/http_auth_random.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use anyhow::Result;
16+
use proxy_wasm_test_framework::{tester, types::*};
17+
use std::env;
18+
19+
fn main() -> Result<()> {
20+
let args: Vec<String> = env::args().collect();
21+
assert_eq!(args.len(), 2);
22+
let http_auth_random_path = &args[1];
23+
let mut http_auth_random = tester::test(http_auth_random_path)?;
24+
25+
http_auth_random
26+
.call_start()
27+
.execute_and_expect(ReturnType::None)?;
28+
29+
let root_context = 1;
30+
http_auth_random
31+
.call_proxy_on_context_create(root_context, 0)
32+
.execute_and_expect(ReturnType::None)?;
33+
34+
let http_context = 2;
35+
http_auth_random
36+
.call_proxy_on_context_create(http_context, root_context)
37+
.execute_and_expect(ReturnType::None)?;
38+
39+
http_auth_random
40+
.call_proxy_on_request_headers(http_context, 0)
41+
.expect_http_call(
42+
"httpbin",
43+
vec![
44+
(":method", "GET"),
45+
(":path", "/bytes/1"),
46+
(":authority", "httpbin.org"),
47+
],
48+
None,
49+
vec![],
50+
5 * 10u64.pow(3),
51+
)
52+
.returning(0)
53+
.execute_and_expect(ReturnType::Action(Action::Pause))?;
54+
55+
let buffer_data = "custom_developer_body";
56+
http_auth_random
57+
.call_proxy_on_http_call_response(http_context, 0, 0, buffer_data.len() as i32, 0)
58+
.expect_get_buffer_bytes(BufferType::HttpCallResponseBody)
59+
.returning(buffer_data)
60+
.expect_send_local_response(
61+
403,
62+
Some("Access forbidden.\n"),
63+
vec![("Powered-By", "proxy-wasm")],
64+
-1,
65+
)
66+
.execute_and_expect(ReturnType::None)?;
67+
68+
http_auth_random
69+
.call_proxy_on_response_headers(http_context, 0)
70+
.expect_replace_header_map_value(MapType::HttpResponseHeaders, "Powered-By", "proxy-wasm")
71+
.execute_and_expect(ReturnType::Action(Action::Continue))?;
72+
73+
return Ok(());
74+
}

examples/http_headers.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use anyhow::Result;
16+
use proxy_wasm_test_framework::{tester, types::*};
17+
use std::env;
18+
19+
fn main() -> Result<()> {
20+
let args: Vec<String> = env::args().collect();
21+
assert_eq!(args.len(), 2);
22+
let http_headers_path = &args[1];
23+
let mut http_headers_test = tester::test(http_headers_path)?;
24+
25+
http_headers_test
26+
.call_start()
27+
.execute_and_expect(ReturnType::None)?;
28+
29+
let root_context = 1;
30+
http_headers_test
31+
.call_proxy_on_context_create(root_context, 0)
32+
.execute_and_expect(ReturnType::None)?;
33+
34+
let http_context = 2;
35+
http_headers_test
36+
.call_proxy_on_context_create(http_context, root_context)
37+
.execute_and_expect(ReturnType::None)?;
38+
39+
http_headers_test
40+
.call_proxy_on_request_headers(http_context, 0)
41+
.expect_get_header_map_pairs(MapType::HttpRequestHeaders)
42+
.returning(vec![
43+
(":method", "GET"),
44+
(":path", "/hello"),
45+
(":authority", "developer"),
46+
])
47+
.expect_get_header_map_value(MapType::HttpRequestHeaders, ":path")
48+
.returning("/hello")
49+
.expect_send_local_response(
50+
200,
51+
Some("Hello, World!\n"),
52+
vec![("Hello", "World"), ("Powered-By", "proxy-wasm")],
53+
-1,
54+
)
55+
.execute_and_expect(ReturnType::Action(Action::Pause))?;
56+
57+
http_headers_test
58+
.call_proxy_on_response_headers(http_context, 0)
59+
.expect_get_header_map_pairs(MapType::HttpResponseHeaders)
60+
.returning(vec![(":status", "200"), ("Powered-By", "proxy-wasm")])
61+
.expect_log(LogLevel::Trace, "#2 <- :status: 200")
62+
.expect_log(LogLevel::Trace, "#2 <- Powered-By: proxy-wasm")
63+
.execute_and_expect(ReturnType::Action(Action::Continue))?;
64+
65+
http_headers_test
66+
.call_proxy_on_log(http_context)
67+
.expect_log(LogLevel::Trace, "#2 completed.")
68+
.execute_and_expect(ReturnType::None)?;
69+
70+
return Ok(());
71+
}

0 commit comments

Comments
 (0)