11use valkey_module:: alloc:: ValkeyAlloc ;
22use valkey_module:: {
3- valkey_module, Context , NextArg , Status , ValkeyError , ValkeyResult , ValkeyString , ValkeyValue ,
3+ valkey_module, ContextTrait , NextArg , Status , ValkeyError , ValkeyResult , ValkeyString ,
4+ ValkeyValue ,
45} ;
56
6- fn get_client_id ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
7+ fn get_client_id ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
78 let client_id = ctx. get_client_id ( ) ;
89 Ok ( ( client_id as i64 ) . into ( ) )
910}
1011
11- fn get_client_name ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
12+ fn get_client_name ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
1213 // test for invalid client_id
1314 match ctx. get_client_name_by_id ( 0 ) {
1415 Ok ( tmp) => ctx. log_notice ( & format ! (
@@ -21,7 +22,7 @@ fn get_client_name(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult {
2122 Ok ( ValkeyValue :: from ( client_name. to_string ( ) ) )
2223}
2324
24- fn get_client_username ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
25+ fn get_client_username ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
2526 // test for invalid client_id
2627 match ctx. get_client_username_by_id ( 0 ) {
2728 Ok ( tmp) => ctx. log_notice ( & format ! (
@@ -34,7 +35,7 @@ fn get_client_username(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult
3435 Ok ( ValkeyValue :: from ( client_username. to_string ( ) ) )
3536}
3637
37- fn set_client_name ( ctx : & Context , args : Vec < ValkeyString > ) -> ValkeyResult {
38+ fn set_client_name ( ctx : & impl ContextTrait , args : Vec < ValkeyString > ) -> ValkeyResult {
3839 if args. len ( ) != 2 {
3940 return Err ( ValkeyError :: WrongArity ) ;
4041 }
@@ -47,7 +48,7 @@ fn set_client_name(ctx: &Context, args: Vec<ValkeyString>) -> ValkeyResult {
4748 Ok ( ValkeyValue :: Integer ( resp2 as i64 ) )
4849}
4950
50- fn get_client_cert ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
51+ fn get_client_cert ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
5152 // unless connection is made with cert, this will return Err, so just log it and return nothing
5253 match ctx. get_client_cert ( ) {
5354 Ok ( tmp) => ctx. log_notice ( & format ! ( "client_cert: {:?}" , tmp. to_string( ) ) ) ,
@@ -56,7 +57,7 @@ fn get_client_cert(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult {
5657 Ok ( "" . into ( ) )
5758}
5859
59- fn get_client_info ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
60+ fn get_client_info ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
6061 // test for invalid client_id
6162 let client_info_by_id = ctx. get_client_info_by_id ( 0 ) ;
6263 ctx. log_notice ( & format ! (
@@ -69,7 +70,7 @@ fn get_client_info(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult {
6970 Ok ( ValkeyValue :: from ( client_info. version . to_string ( ) ) )
7071}
7172
72- fn get_client_ip ( ctx : & Context , _args : Vec < ValkeyString > ) -> ValkeyResult {
73+ fn get_client_ip ( ctx : & impl ContextTrait , _args : Vec < ValkeyString > ) -> ValkeyResult {
7374 // test for invalid client_id
7475 let client_ip_by_id = ctx. get_client_ip_by_id ( 0 ) ;
7576 ctx. log_notice ( & format ! (
@@ -79,7 +80,7 @@ fn get_client_ip(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult {
7980 Ok ( ctx. get_client_ip ( ) ?. into ( ) )
8081}
8182
82- fn deauth_client_by_id ( ctx : & Context , args : Vec < ValkeyString > ) -> ValkeyResult {
83+ fn deauth_client_by_id ( ctx : & impl ContextTrait , args : Vec < ValkeyString > ) -> ValkeyResult {
8384 if args. len ( ) != 2 {
8485 return Err ( ValkeyError :: WrongArity ) ;
8586 }
@@ -95,7 +96,7 @@ fn deauth_client_by_id(ctx: &Context, args: Vec<ValkeyString>) -> ValkeyResult {
9596 }
9697}
9798
98- fn config_get ( ctx : & Context , args : Vec < ValkeyString > ) -> ValkeyResult {
99+ fn config_get ( ctx : & impl ContextTrait , args : Vec < ValkeyString > ) -> ValkeyResult {
99100 if args. len ( ) != 2 {
100101 return Err ( ValkeyError :: WrongArity ) ;
101102 }
@@ -125,3 +126,152 @@ valkey_module! {
125126 [ "client.config_get" , config_get, "" , 0 , 0 , 0 ]
126127 ]
127128}
129+
130+ #[ cfg( test) ]
131+ mod tests {
132+ use super :: * ;
133+ use std:: ptr:: null_mut;
134+ use valkey_module:: { MockContext , RedisModuleClientInfo } ;
135+
136+ fn null_valkey_string ( ) -> ValkeyString {
137+ ValkeyString :: from_redis_module_string ( null_mut ( ) , null_mut ( ) )
138+ }
139+
140+ fn module_client_info ( id : u64 ) -> RedisModuleClientInfo {
141+ RedisModuleClientInfo {
142+ version : 1 ,
143+ flags : 0 ,
144+ id,
145+ addr : [ 0 ; 46 ] ,
146+ port : 6379 ,
147+ db : 0 ,
148+ }
149+ }
150+
151+ #[ test]
152+ fn test_get_client_id ( ) {
153+ let mut ctx = MockContext :: new ( ) ;
154+ ctx. expect_get_client_id ( ) . times ( 1 ) . returning ( || 42 ) ;
155+ let reply = get_client_id ( & ctx, vec ! [ ] ) . unwrap ( ) ;
156+ assert_eq ! ( reply, ValkeyValue :: Integer ( 42 ) ) ;
157+ }
158+
159+ #[ test]
160+ fn test_get_client_name ( ) {
161+ let mut ctx = MockContext :: new ( ) ;
162+ ctx. expect_log_notice ( ) . times ( 1 ) . return_const ( ( ) ) ;
163+ ctx. expect_get_client_name_by_id ( )
164+ . times ( 1 )
165+ . returning ( |_| Err ( ValkeyError :: Str ( "no such client" ) ) ) ;
166+ ctx. expect_get_client_name ( )
167+ . times ( 1 )
168+ . returning ( || Err ( ValkeyError :: Str ( "no name" ) ) ) ;
169+
170+ let err = get_client_name ( & ctx, vec ! [ ] ) . unwrap_err ( ) ;
171+ assert ! ( matches!( err, ValkeyError :: Str ( "no name" ) ) ) ;
172+ }
173+
174+ #[ test]
175+ fn test_get_client_username ( ) {
176+ let mut ctx = MockContext :: new ( ) ;
177+ ctx. expect_log_notice ( ) . times ( 1 ) . return_const ( ( ) ) ;
178+ ctx. expect_get_client_username_by_id ( )
179+ . times ( 1 )
180+ . returning ( |_| Err ( ValkeyError :: Str ( "no such client" ) ) ) ;
181+ ctx. expect_get_client_username ( )
182+ . times ( 1 )
183+ . returning ( || Err ( ValkeyError :: Str ( "no user" ) ) ) ;
184+
185+ let err = get_client_username ( & ctx, vec ! [ ] ) . unwrap_err ( ) ;
186+ assert ! ( matches!( err, ValkeyError :: Str ( "no user" ) ) ) ;
187+ }
188+
189+ #[ test]
190+ fn test_set_client_name_wrong_arity ( ) {
191+ let ctx = MockContext :: new ( ) ;
192+ let err = set_client_name ( & ctx, vec ! [ null_valkey_string( ) ] ) . unwrap_err ( ) ;
193+ assert ! ( matches!( err, ValkeyError :: WrongArity ) ) ;
194+ }
195+
196+ #[ test]
197+ fn test_set_client_name ( ) {
198+ let mut ctx = MockContext :: new ( ) ;
199+ ctx. expect_log_notice ( ) . times ( 1 ) . return_const ( ( ) ) ;
200+ ctx. expect_set_client_name_by_id ( )
201+ . times ( 1 )
202+ . returning ( |_, _| Status :: Ok ) ;
203+ ctx. expect_set_client_name ( )
204+ . times ( 1 )
205+ . returning ( |_| Status :: Ok ) ;
206+
207+ let reply =
208+ set_client_name ( & ctx, vec ! [ null_valkey_string( ) , null_valkey_string( ) ] ) . unwrap ( ) ;
209+ assert_eq ! ( reply, ValkeyValue :: Integer ( Status :: Ok as i64 ) ) ;
210+ }
211+
212+ #[ test]
213+ fn test_get_client_cert ( ) {
214+ let mut ctx = MockContext :: new ( ) ;
215+ ctx. expect_log_notice ( ) . times ( 1 ) . return_const ( ( ) ) ;
216+ ctx. expect_get_client_cert ( )
217+ . times ( 1 )
218+ . returning ( || Err ( ValkeyError :: Str ( "no cert" ) ) ) ;
219+ let reply = get_client_cert ( & ctx, vec ! [ ] ) . unwrap ( ) ;
220+ assert_eq ! ( reply, ValkeyValue :: BulkString ( String :: new( ) ) ) ;
221+ }
222+
223+ #[ test]
224+ fn test_get_client_info ( ) {
225+ let mut ctx = MockContext :: new ( ) ;
226+ ctx. expect_log_notice ( ) . times ( 2 ) . return_const ( ( ) ) ;
227+ ctx. expect_get_client_info_by_id ( )
228+ . times ( 1 )
229+ . returning ( |_| Ok ( module_client_info ( 0 ) ) ) ;
230+ ctx. expect_get_client_info ( )
231+ . times ( 1 )
232+ . returning ( || Ok ( module_client_info ( 42 ) ) ) ;
233+
234+ let reply = get_client_info ( & ctx, vec ! [ ] ) . unwrap ( ) ;
235+ assert_eq ! ( reply, ValkeyValue :: BulkString ( "1" . to_string( ) ) ) ;
236+ }
237+
238+ #[ test]
239+ fn test_get_client_ip ( ) {
240+ let mut ctx = MockContext :: new ( ) ;
241+ ctx. expect_get_client_ip_by_id ( )
242+ . times ( 1 )
243+ . returning ( |_| Ok ( "0.0.0.0" . to_string ( ) ) ) ;
244+ ctx. expect_log_notice ( ) . times ( 1 ) . return_const ( ( ) ) ;
245+ ctx. expect_get_client_ip ( )
246+ . times ( 1 )
247+ . returning ( || Ok ( "127.0.0.1" . to_string ( ) ) ) ;
248+ let reply = get_client_ip ( & ctx, vec ! [ ] ) . unwrap ( ) ;
249+ assert_eq ! ( reply, ValkeyValue :: BulkString ( "127.0.0.1" . to_string( ) ) ) ;
250+ }
251+
252+ #[ test]
253+ fn test_deauth_client_by_id_wrong_arity ( ) {
254+ let ctx = MockContext :: new ( ) ;
255+ let err = deauth_client_by_id ( & ctx, vec ! [ null_valkey_string( ) ] ) . unwrap_err ( ) ;
256+ assert ! ( matches!( err, ValkeyError :: WrongArity ) ) ;
257+ }
258+
259+ #[ test]
260+ #[ ignore]
261+ fn test_death_client_by_id ( ) {
262+ // TODO - test when ValkeyString is unit testable
263+ }
264+
265+ #[ test]
266+ fn test_config_get_wrong_arity ( ) {
267+ let ctx = MockContext :: new ( ) ;
268+ let err = config_get ( & ctx, vec ! [ null_valkey_string( ) ] ) . unwrap_err ( ) ;
269+ assert ! ( matches!( err, ValkeyError :: WrongArity ) ) ;
270+ }
271+
272+ #[ test]
273+ #[ ignore]
274+ fn test_config_get ( ) {
275+ // TODO - test when ValkeyString is unit testable
276+ }
277+ }
0 commit comments