Skip to content

Commit 41b920d

Browse files
committed
[refactor] Operation responsible of providing hostcalls fns
* Easier to test, mocking fn * Assigned fn on creation, default hostcall and mock on tests Signed-off-by: dd di cesare <[email protected]>
1 parent 159d247 commit 41b920d

File tree

2 files changed

+71
-67
lines changed

2 files changed

+71
-67
lines changed

src/operation_dispatcher.rs

+59-61
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::configuration::{Extension, ExtensionType, FailureMode};
22
use crate::envoy::RateLimitDescriptor;
33
use crate::policy::Policy;
4-
use crate::service::{GrpcMessage, GrpcServiceHandler};
4+
use crate::service::{GetMapValuesBytes, GrpcCall, GrpcMessage, GrpcServiceHandler};
55
use protobuf::RepeatedField;
66
use proxy_wasm::hostcalls;
7-
use proxy_wasm::types::Status;
7+
use proxy_wasm::types::{Bytes, MapType, Status};
88
use std::cell::RefCell;
99
use std::collections::HashMap;
1010
use std::rc::Rc;
@@ -29,24 +29,6 @@ impl State {
2929
}
3030
}
3131

32-
fn grpc_call(
33-
upstream_name: &str,
34-
service_name: &str,
35-
method_name: &str,
36-
initial_metadata: Vec<(&str, &[u8])>,
37-
message: Option<&[u8]>,
38-
timeout: Duration,
39-
) -> Result<u32, Status> {
40-
hostcalls::dispatch_grpc_call(
41-
upstream_name,
42-
service_name,
43-
method_name,
44-
initial_metadata,
45-
message,
46-
timeout,
47-
)
48-
}
49-
5032
type Procedure = (Rc<GrpcServiceHandler>, GrpcMessage);
5133

5234
#[allow(dead_code)]
@@ -56,6 +38,8 @@ pub(crate) struct Operation {
5638
result: Result<u32, Status>,
5739
extension: Rc<Extension>,
5840
procedure: Procedure,
41+
grpc_call: GrpcCall,
42+
get_map_values_bytes: GetMapValuesBytes,
5943
}
6044

6145
#[allow(dead_code)]
@@ -66,17 +50,19 @@ impl Operation {
6650
result: Err(Status::Empty),
6751
extension,
6852
procedure,
53+
grpc_call,
54+
get_map_values_bytes,
6955
}
7056
}
7157

72-
pub fn set_action(&mut self, procedure: Procedure) {
73-
self.procedure = procedure;
74-
}
75-
76-
pub fn trigger(&mut self) {
58+
fn trigger(&mut self) {
7759
if let State::Done = self.state {
7860
} else {
79-
self.result = self.procedure.0.send(grpc_call, self.procedure.1.clone());
61+
self.result = self.procedure.0.send(
62+
self.get_map_values_bytes,
63+
self.grpc_call,
64+
self.procedure.1.clone(),
65+
);
8066
self.state.next();
8167
}
8268
}
@@ -172,6 +158,28 @@ impl OperationDispatcher {
172158
}
173159
}
174160

161+
fn grpc_call(
162+
upstream_name: &str,
163+
service_name: &str,
164+
method_name: &str,
165+
initial_metadata: Vec<(&str, &[u8])>,
166+
message: Option<&[u8]>,
167+
timeout: Duration,
168+
) -> Result<u32, Status> {
169+
hostcalls::dispatch_grpc_call(
170+
upstream_name,
171+
service_name,
172+
method_name,
173+
initial_metadata,
174+
message,
175+
timeout,
176+
)
177+
}
178+
179+
fn get_map_values_bytes(map_type: MapType, key: &str) -> Result<Option<Bytes>, Status> {
180+
hostcalls::get_map_value_bytes(map_type, key)
181+
}
182+
175183
#[cfg(test)]
176184
mod tests {
177185
use super::*;
@@ -189,6 +197,10 @@ mod tests {
189197
Ok(200)
190198
}
191199

200+
fn get_map_values_bytes(_map_type: MapType, _key: &str) -> Result<Option<Bytes>, Status> {
201+
Ok(Some(Vec::new()))
202+
}
203+
192204
fn build_grpc_service_handler() -> GrpcServiceHandler {
193205
GrpcServiceHandler::new(Rc::new(Default::default()), Rc::new(Default::default()))
194206
}
@@ -203,33 +215,33 @@ mod tests {
203215
}
204216
}
205217

206-
#[test]
207-
fn operation_getters() {
208-
let extension = Rc::new(Extension::default());
209-
let operation = Operation::new(
210-
extension,
211-
(
218+
fn build_operation() -> Operation {
219+
Operation {
220+
state: State::Pending,
221+
result: Ok(200),
222+
extension: Rc::new(Extension::default()),
223+
procedure: (
212224
Rc::new(build_grpc_service_handler()),
213225
GrpcMessage::RateLimit(build_message()),
214226
),
215-
);
227+
grpc_call,
228+
get_map_values_bytes,
229+
}
230+
}
231+
232+
#[test]
233+
fn operation_getters() {
234+
let operation = build_operation();
216235

217236
assert_eq!(operation.get_state(), State::Pending);
218237
assert_eq!(operation.get_extension_type(), ExtensionType::RateLimit);
219238
assert_eq!(operation.get_failure_mode(), FailureMode::Deny);
220-
assert_eq!(operation.get_result(), Result::Ok(1));
239+
assert_eq!(operation.get_result(), Ok(200));
221240
}
222241

223242
#[test]
224243
fn operation_transition() {
225-
let extension = Rc::new(Extension::default());
226-
let mut operation = Operation::new(
227-
extension,
228-
(
229-
Rc::new(build_grpc_service_handler()),
230-
GrpcMessage::RateLimit(build_message()),
231-
),
232-
);
244+
let mut operation = build_operation();
233245
assert_eq!(operation.get_state(), State::Pending);
234246
operation.trigger();
235247
assert_eq!(operation.get_state(), State::Waiting);
@@ -242,23 +254,16 @@ mod tests {
242254
fn operation_dispatcher_push_actions() {
243255
let operation_dispatcher = OperationDispatcher::default();
244256

245-
assert_eq!(operation_dispatcher.operations.borrow().len(), 1);
246-
let extension = Rc::new(Extension::default());
247-
operation_dispatcher.push_operations(vec![Operation::new(
248-
extension,
249-
(
250-
Rc::new(build_grpc_service_handler()),
251-
GrpcMessage::RateLimit(build_message()),
252-
),
253-
)]);
257+
assert_eq!(operation_dispatcher.operations.borrow().len(), 0);
258+
operation_dispatcher.push_operations(vec![build_operation()]);
254259

255-
assert_eq!(operation_dispatcher.operations.borrow().len(), 2);
260+
assert_eq!(operation_dispatcher.operations.borrow().len(), 1);
256261
}
257262

258263
#[test]
259264
fn operation_dispatcher_get_current_action_state() {
260265
let operation_dispatcher = OperationDispatcher::default();
261-
266+
operation_dispatcher.push_operations(vec![build_operation()]);
262267
assert_eq!(
263268
operation_dispatcher.get_current_operation_state(),
264269
Some(State::Pending)
@@ -267,14 +272,7 @@ mod tests {
267272

268273
#[test]
269274
fn operation_dispatcher_next() {
270-
let extension = Rc::new(Extension::default());
271-
let operation = Operation::new(
272-
extension,
273-
(
274-
Rc::new(build_grpc_service_handler()),
275-
GrpcMessage::RateLimit(build_message()),
276-
),
277-
);
275+
let operation = build_operation();
278276
let operation_dispatcher = OperationDispatcher::default();
279277
operation_dispatcher.push_operations(vec![operation]);
280278

src/service.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use protobuf::reflect::MessageDescriptor;
1010
use protobuf::{
1111
Clear, CodedInputStream, CodedOutputStream, Message, ProtobufResult, UnknownFields,
1212
};
13-
use proxy_wasm::hostcalls;
1413
use proxy_wasm::types::{Bytes, MapType, Status};
1514
use std::any::Any;
1615
use std::cell::OnceCell;
@@ -182,7 +181,7 @@ impl GrpcService {
182181
}
183182
}
184183

185-
type GrpcCall = fn(
184+
pub type GrpcCall = fn(
186185
upstream_name: &str,
187186
service_name: &str,
188187
method_name: &str,
@@ -191,6 +190,8 @@ type GrpcCall = fn(
191190
timeout: Duration,
192191
) -> Result<u32, Status>;
193192

193+
pub type GetMapValuesBytes = fn(map_type: MapType, key: &str) -> Result<Option<Bytes>, Status>;
194+
194195
pub struct GrpcServiceHandler {
195196
service: Rc<GrpcService>,
196197
header_resolver: Rc<HeaderResolver>,
@@ -204,11 +205,16 @@ impl GrpcServiceHandler {
204205
}
205206
}
206207

207-
pub fn send(&self, grpc_call: GrpcCall, message: GrpcMessage) -> Result<u32, Status> {
208+
pub fn send(
209+
&self,
210+
get_map_values_bytes: GetMapValuesBytes,
211+
grpc_call: GrpcCall,
212+
message: GrpcMessage,
213+
) -> Result<u32, Status> {
208214
let msg = Message::write_to_bytes(&message).unwrap();
209215
let metadata = self
210216
.header_resolver
211-
.get()
217+
.get(get_map_values_bytes)
212218
.iter()
213219
.map(|(header, value)| (*header, value.as_slice()))
214220
.collect();
@@ -249,12 +255,12 @@ impl HeaderResolver {
249255
}
250256
}
251257

252-
pub fn get(&self) -> &Vec<(&'static str, Bytes)> {
258+
pub fn get(&self, get_map_values_bytes: GetMapValuesBytes) -> &Vec<(&'static str, Bytes)> {
253259
self.headers.get_or_init(|| {
254260
let mut headers = Vec::new();
255261
for header in TracingHeader::all() {
256262
if let Ok(Some(value)) =
257-
hostcalls::get_map_value_bytes(MapType::HttpRequestHeaders, (*header).as_str())
263+
get_map_values_bytes(MapType::HttpRequestHeaders, (*header).as_str())
258264
{
259265
headers.push(((*header).as_str(), value));
260266
}

0 commit comments

Comments
 (0)