From 4fa7fcba0149d4504a1e6f7e4e7fcdef51719b29 Mon Sep 17 00:00:00 2001 From: 007gzs <007gzs@gmail.com> Date: Fri, 19 Dec 2025 14:40:27 +0800 Subject: [PATCH] Rust Plugin add Rule matcher test (#3230) --- .../example/wrapper-say-hello/src/lib.rs | 26 ++++----- plugins/wasm-rust/src/rule_matcher.rs | 57 +++++++++++++++++-- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/plugins/wasm-rust/example/wrapper-say-hello/src/lib.rs b/plugins/wasm-rust/example/wrapper-say-hello/src/lib.rs index 916acb724..1ffa56990 100644 --- a/plugins/wasm-rust/example/wrapper-say-hello/src/lib.rs +++ b/plugins/wasm-rust/example/wrapper-say-hello/src/lib.rs @@ -35,7 +35,6 @@ struct SayHelloRoot { } struct SayHello { - rule_matcher: SharedRuleMatcher, log: Log, config: Option>, weak: Weak>>>, @@ -43,6 +42,7 @@ struct SayHello { #[derive(Default, Debug, Deserialize, Clone)] struct SayHelloConfig { + #[serde(default)] name: String, } @@ -92,7 +92,6 @@ impl RootContextWrapper for SayHelloRoot { Some(Box::new(SayHello { log: Log::new(PLUGIN_NAME.to_string()), config: None, - rule_matcher: Rc::new(RefCell::new(RuleMatcher::default())), weak: Default::default(), })) } @@ -122,20 +121,15 @@ impl HttpContextWrapper for SayHello { &mut self, _headers: &multimap::MultiMap, ) -> HeaderAction { - let binding = self.rule_matcher.borrow(); - let config = match binding.get_match_config() { - None => { - self.send_http_response(200, vec![], Some("Hello, World!".as_bytes())); - return HeaderAction::Continue; - } - Some(config) => config.1, - }; - - self.send_http_response( - 200, - vec![], - Some(format!("Hello, {}!", config.name).as_bytes()), - ); + if let Some(config) = &self.config { + self.send_http_response( + 200, + vec![], + Some(format!("Hello, {}!", config.name).as_bytes()), + ); + } else { + self.send_http_response(200, vec![], Some("Hello, World!".as_bytes())); + } HeaderAction::Continue } diff --git a/plugins/wasm-rust/src/rule_matcher.rs b/plugins/wasm-rust/src/rule_matcher.rs index cef8d50fe..89db822a9 100644 --- a/plugins/wasm-rust/src/rule_matcher.rs +++ b/plugins/wasm-rust/src/rule_matcher.rs @@ -176,16 +176,23 @@ where let service_name = String::from_utf8(get_property(vec!["cluster_name"]).unwrap_or_default()) .unwrap_or_else(|_| "".to_string()); - + self.get_match_config_by_args(&host, &route_name, &service_name) + } + fn get_match_config_by_args( + &self, + host: &str, + route_name: &str, + service_name: &str, + ) -> Option<(i64, Rc)> { for (i, rule) in self.rule_config.iter().enumerate() { match rule.category { Category::Host => { - if self.host_match(rule, host.as_str()) { + if self.host_match(rule, host) { return Some((i as i64, rule.config.clone())); } } Category::Route => { - if rule.routes.contains(route_name.as_str()) { + if rule.routes.contains(route_name) { return Some((i as i64, rule.config.clone())); } } @@ -197,7 +204,7 @@ where } } Category::Service => { - if self.service_match(rule, &service_name) { + if self.service_match(rule, service_name) { return Some((i as i64, rule.config.clone())); } } @@ -639,6 +646,48 @@ mod tests { } } + #[test] + fn test_match_route_config() { + let mut rule: RuleMatcher = RuleMatcher::default(); + + let res = rule.parse_rule_config( + &serde_json::from_str( + r#"{"_rules_":[{"_match_route_":["test1","test2"],"name":"ann", "age":16}]}"#, + ) + .unwrap(), + ); + assert!(res.is_ok()); + let config = rule.get_match_config_by_args("test", "test", "test"); + assert!(config.is_none()); + let config = rule.get_match_config_by_args("test", "test1", "test"); + assert!(config.is_some()); + let c = config.unwrap(); + assert_eq!(c.1.name, "ann"); + assert_eq!(c.1.age, 16); + + let config = rule.get_match_config_by_args("test", "test2", "test"); + assert!(config.is_some()); + let c = config.unwrap(); + assert_eq!(c.1.name, "ann"); + assert_eq!(c.1.age, 16); + } + + #[test] + fn test_match_route1_config() { + let mut rule: RuleMatcher = RuleMatcher::default(); + + let res = rule.parse_rule_config( + &serde_json::from_str(r#"{"_rules_":[{"_match_route_":["test1"]}]}"#).unwrap(), + ); + assert!(res.is_ok()); + let config = rule.get_match_config_by_args("test", "test", "test"); + assert!(config.is_none()); + let config = rule.get_match_config_by_args("test", "test1", "test"); + assert!(config.is_some()); + let c = config.unwrap(); + assert_eq!(c.1.name, ""); + assert_eq!(c.1.age, 0); + } #[derive(Default, Clone, Deserialize, PartialEq, Eq)] struct CompleteConfig { // global config