Skip to content

Commit 3ce2442

Browse files
authored
Cpp host support, high-level testing, and fixed default simulator responses (#10)
Signed-off-by: Christopher Agia <chrisagia@google.com>
1 parent 94d51dc commit 3ce2442

File tree

5 files changed

+1503
-693
lines changed

5 files changed

+1503
-693
lines changed

examples/http_headers_high_level.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;
17+
use proxy_wasm_test_framework::types::*;
18+
use structopt::StructOpt;
19+
20+
fn main() -> Result<()> {
21+
let args = tester::MockSettings::from_args();
22+
let mut http_headers_test = tester::mock(args)?;
23+
24+
let root_context = 1;
25+
let http_context = 2;
26+
http_headers_test
27+
.call_start()
28+
.call_proxy_on_context_create(root_context, 0)
29+
.call_proxy_on_context_create(http_context, root_context)
30+
.execute_and_expect_n(vec![ReturnType::None, ReturnType::None, ReturnType::None])?;
31+
32+
http_headers_test
33+
.http_request(
34+
http_context,
35+
Some(vec![
36+
(":method", "GET"),
37+
(":path", "/hello"),
38+
(":authority", "developer"),
39+
]),
40+
None,
41+
None,
42+
)?
43+
.expect_log(Some(LogLevel::Trace), Some("#2 -> :method: GET"))
44+
.expect_log(Some(LogLevel::Trace), Some("#2 -> :path: /hello"))
45+
.expect_log(Some(LogLevel::Trace), Some("#2 -> :authority: developer"))
46+
.expect_send_local_response(
47+
Some(200),
48+
Some("Hello, World!\n"),
49+
Some(vec![("Hello", "World"), ("Powered-By", "proxy-wasm")]),
50+
Some(-1),
51+
)
52+
.execute_and_expect_n(vec![ReturnType::Action(Action::Pause)])?;
53+
54+
http_headers_test
55+
.http_response(
56+
http_context,
57+
Some(vec![(":status", "200"), ("Powered-By", "proxy-wasm")]),
58+
None,
59+
None,
60+
)?
61+
.expect_log(Some(LogLevel::Trace), Some("#2 <- :status: 200"))
62+
.expect_log(Some(LogLevel::Trace), Some("#2 <- Powered-By: proxy-wasm"))
63+
.execute_and_expect_n(vec![ReturnType::Action(Action::Continue)])?;
64+
65+
http_headers_test
66+
.call_proxy_on_log(http_context)
67+
.expect_log(Some(LogLevel::Trace), Some("#2 completed."))
68+
.execute_and_expect(ReturnType::None)?;
69+
70+
return Ok(());
71+
}

src/host_settings.rs

Lines changed: 83 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ impl HostHandle {
4444
pub struct HostSettings {
4545
abi_version: AbiVersion,
4646
quiet: bool,
47+
effective_context_id: i32,
4748
tick_period_millis: Duration,
48-
header_map_pairs: HashMap<i32, HashMap<String, String>>,
49+
header_map_pairs: HashMap<i32, Vec<(String, String)>>,
4950
buffer_bytes: HashMap<i32, Bytes>,
5051
}
5152

@@ -54,6 +55,7 @@ impl HostSettings {
5455
HostSettings {
5556
abi_version: abi_version,
5657
quiet: quiet,
58+
effective_context_id: -1,
5759
tick_period_millis: Duration::new(0, 0),
5860
header_map_pairs: default_header_map_pairs(),
5961
buffer_bytes: default_buffer_bytes(),
@@ -76,6 +78,14 @@ impl HostSettings {
7678
self.quiet
7779
}
7880

81+
pub fn set_effective_context(&mut self, effective_context_id: i32) {
82+
self.effective_context_id = effective_context_id;
83+
}
84+
85+
pub fn get_effective_context(&mut self) -> i32 {
86+
self.effective_context_id
87+
}
88+
7989
pub fn reset_tick_period_millis(&mut self) {
8090
self.tick_period_millis = Duration::from_millis(0u64);
8191
}
@@ -107,9 +117,9 @@ impl HostSettings {
107117
}
108118

109119
pub fn set_header_map_pairs(&mut self, map_type: i32, header_map_pairs: Vec<(&str, &str)>) {
110-
let mut header_map = HashMap::new();
120+
let mut header_map = Vec::new();
111121
for (header_map_key, header_map_value) in header_map_pairs.into_iter() {
112-
header_map.insert(header_map_key.to_string(), header_map_value.to_string());
122+
header_map.push((header_map_key.to_string(), header_map_value.to_string()));
113123
}
114124
self.header_map_pairs.insert(map_type, header_map);
115125
}
@@ -124,9 +134,14 @@ impl HostSettings {
124134
}
125135

126136
pub fn get_header_map_value(&self, map_type: i32, header_map_key: &str) -> Option<String> {
137+
let mut header_map_value: Option<String> = None;
127138
let header_map = self.header_map_pairs.get(&map_type).unwrap();
128-
let header_map_value = header_map.get(header_map_key);
129-
header_map_value.map(|str_val| str_val.to_string())
139+
for (key, value) in header_map {
140+
if key == header_map_key {
141+
header_map_value = Some(value.to_string());
142+
}
143+
}
144+
header_map_value
130145
}
131146

132147
pub fn replace_header_map_value(
@@ -135,13 +150,27 @@ impl HostSettings {
135150
header_map_key: &str,
136151
header_map_value: &str,
137152
) {
138-
let header_map = self.header_map_pairs.get_mut(&map_type).unwrap();
139-
header_map.insert(header_map_key.to_string(), header_map_value.to_string());
153+
let mut new_header_map: Vec<(String, String)> = Vec::new();
154+
let header_map = self.header_map_pairs.get(&map_type).unwrap();
155+
for (key, value) in header_map {
156+
if key != header_map_key {
157+
new_header_map.push((key.to_string(), value.to_string()));
158+
} else {
159+
new_header_map.push((key.to_string(), header_map_value.to_string()));
160+
}
161+
}
162+
self.header_map_pairs.insert(map_type, new_header_map);
140163
}
141164

142165
pub fn remove_header_map_value(&mut self, map_type: i32, header_map_key: &str) {
143-
let header_map = self.header_map_pairs.get_mut(&map_type).unwrap();
144-
header_map.remove(header_map_key);
166+
let mut new_header_map: Vec<(String, String)> = Vec::new();
167+
let header_map = self.header_map_pairs.get(&map_type).unwrap();
168+
for (key, value) in header_map {
169+
if key != header_map_key {
170+
new_header_map.push((key.to_string(), value.to_string()));
171+
}
172+
}
173+
self.header_map_pairs.insert(map_type, new_header_map);
145174
}
146175

147176
pub fn add_header_map_value(
@@ -150,79 +179,91 @@ impl HostSettings {
150179
header_map_key: &str,
151180
header_map_value: &str,
152181
) {
153-
let header_map = self.header_map_pairs.get_mut(&map_type).unwrap();
154-
header_map.insert(header_map_key.to_string(), header_map_value.to_string());
182+
let mut key_found = false;
183+
let mut new_header_map: Vec<(String, String)> = Vec::new();
184+
let header_map = self.header_map_pairs.get(&map_type).unwrap();
185+
for (key, value) in header_map {
186+
if key != header_map_key {
187+
new_header_map.push((key.to_string(), value.to_string()));
188+
} else {
189+
key_found = true;
190+
}
191+
}
192+
if !key_found {
193+
new_header_map.push((header_map_key.to_string(), header_map_value.to_string()));
194+
}
195+
self.header_map_pairs.insert(map_type, new_header_map);
155196
}
156197
}
157198

158199
// functions to retrieve default values
159-
pub fn default_header_map_pairs() -> HashMap<i32, HashMap<String, String>> {
200+
pub fn default_header_map_pairs() -> HashMap<i32, Vec<(String, String)>> {
160201
let mut default_header_maps = HashMap::new();
161202

162-
let mut http_on_request_headers = HashMap::new();
163-
http_on_request_headers.insert(":method".to_string(), "GET".to_string());
164-
http_on_request_headers.insert(
203+
let mut http_on_request_headers = Vec::new();
204+
http_on_request_headers.push((":method".to_string(), "GET".to_string()));
205+
http_on_request_headers.push((
165206
":path".to_string(),
166207
"/default/request/headers/path".to_string(),
167-
);
168-
http_on_request_headers.insert(":authority".to_string(), "abi_test_harness".to_string());
208+
));
209+
http_on_request_headers.push((":authority".to_string(), "abi_test_harness".to_string()));
169210
default_header_maps.insert(MapType::HttpRequestHeaders as i32, http_on_request_headers);
170211

171-
let mut http_on_request_trailers = HashMap::new();
172-
http_on_request_trailers.insert(":method".to_string(), "GET".to_string());
173-
http_on_request_trailers.insert(
212+
let mut http_on_request_trailers = Vec::new();
213+
http_on_request_trailers.push((":method".to_string(), "GET".to_string()));
214+
http_on_request_trailers.push((
174215
":path".to_string(),
175216
"/default/request/trailers/path".to_string(),
176-
);
177-
http_on_request_trailers.insert(":authority".to_string(), "abi_test_harness".to_string());
217+
));
218+
http_on_request_trailers.push((":authority".to_string(), "abi_test_harness".to_string()));
178219
default_header_maps.insert(
179220
MapType::HttpRequestTrailers as i32,
180221
http_on_request_trailers,
181222
);
182223

183-
let mut http_on_response_headers = HashMap::new();
184-
http_on_response_headers.insert(":method".to_string(), "GET".to_string());
185-
http_on_response_headers.insert(
224+
let mut http_on_response_headers = Vec::new();
225+
http_on_response_headers.push((":method".to_string(), "GET".to_string()));
226+
http_on_response_headers.push((
186227
":path".to_string(),
187228
"/default/response/headers/path".to_string(),
188-
);
189-
http_on_response_headers.insert(":authority".to_string(), "abi_test_harness".to_string());
229+
));
230+
http_on_response_headers.push((":authority".to_string(), "abi_test_harness".to_string()));
190231
default_header_maps.insert(
191232
MapType::HttpResponseHeaders as i32,
192233
http_on_response_headers,
193234
);
194235

195-
let mut http_on_response_trailers = HashMap::new();
196-
http_on_response_trailers.insert(":method".to_string(), "GET".to_string());
197-
http_on_response_trailers.insert(
236+
let mut http_on_response_trailers = Vec::new();
237+
http_on_response_trailers.push((":method".to_string(), "GET".to_string()));
238+
http_on_response_trailers.push((
198239
":path".to_string(),
199240
"/default/response/trailers/path".to_string(),
200-
);
201-
http_on_response_trailers.insert(":authority".to_string(), "abi_test_harness".to_string());
241+
));
242+
http_on_response_trailers.push((":authority".to_string(), "abi_test_harness".to_string()));
202243
default_header_maps.insert(
203244
MapType::HttpResponseTrailers as i32,
204245
http_on_response_trailers,
205246
);
206247

207-
let mut http_call_response_headers = HashMap::new();
208-
http_call_response_headers.insert(":method".to_string(), "GET".to_string());
209-
http_call_response_headers.insert(
248+
let mut http_call_response_headers = Vec::new();
249+
http_call_response_headers.push((":method".to_string(), "GET".to_string()));
250+
http_call_response_headers.push((
210251
":path".to_string(),
211252
"/default/call/response/headers/path".to_string(),
212-
);
213-
http_call_response_headers.insert(":authority".to_string(), "abi_test_harness".to_string());
253+
));
254+
http_call_response_headers.push((":authority".to_string(), "abi_test_harness".to_string()));
214255
default_header_maps.insert(
215256
MapType::HttpCallResponseHeaders as i32,
216257
http_call_response_headers,
217258
);
218259

219-
let mut http_call_response_trailers = HashMap::new();
220-
http_call_response_trailers.insert(":method".to_string(), "GET".to_string());
221-
http_call_response_trailers.insert(
260+
let mut http_call_response_trailers = Vec::new();
261+
http_call_response_trailers.push((":method".to_string(), "GET".to_string()));
262+
http_call_response_trailers.push((
222263
":path".to_string(),
223264
"/default/call/response/trailers/path".to_string(),
224-
);
225-
http_call_response_trailers.insert(":authority".to_string(), "abi_test_harness".to_string());
265+
));
266+
http_call_response_trailers.push((":authority".to_string(), "abi_test_harness".to_string()));
226267
default_header_maps.insert(
227268
MapType::HttpCallResponseTrailers as i32,
228269
http_call_response_trailers,

0 commit comments

Comments
 (0)