@@ -800,3 +800,99 @@ async fn test_adminspace_transports_and_links() {
800800 router2. close ( ) . await . unwrap ( ) ;
801801 router1. close ( ) . await . unwrap ( ) ;
802802}
803+
804+ #[ cfg( feature = "stats" ) ]
805+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 4 ) ]
806+ async fn test_adminspace_regression_1 ( ) {
807+ const TIMEOUT : Duration = Duration :: from_secs ( 60 ) ;
808+ const ROUTER_ENDPOINT : & str = "tcp/localhost:31002" ;
809+ const ROUTER_CONNECT_ENDPOINT : & str = "tcp/localhost:31002?rel=1;prio=1-7" ;
810+
811+ zenoh_util:: init_log_from_env_or ( "error" ) ;
812+
813+ // Create router1 with adminspace enabled
814+ let router1 = {
815+ let mut c = zenoh_config:: Config :: default ( ) ;
816+ c. set_mode ( Some ( WhatAmI :: Router ) ) . unwrap ( ) ;
817+ c. listen
818+ . endpoints
819+ . set ( vec ! [ ROUTER_ENDPOINT . parse:: <EndPoint >( ) . unwrap( ) ] )
820+ . unwrap ( ) ;
821+ c. scouting . multicast . set_enabled ( Some ( false ) ) . unwrap ( ) ;
822+ c. adminspace . set_enabled ( true ) . unwrap ( ) ;
823+ c. adminspace . permissions . set_read ( true ) . unwrap ( ) ;
824+ c. adminspace . permissions . set_write ( false ) . unwrap ( ) ;
825+ // Enable QoS for priorities and reliability support
826+ c. transport . unicast . qos . set_enabled ( true ) . unwrap ( ) ;
827+ ztimeout ! ( zenoh:: open( c) ) . unwrap ( )
828+ } ;
829+ let zid1 = router1. zid ( ) ;
830+
831+ // Create router2 that connects to router1 (creates unicast transport)
832+ let _router2 = {
833+ let mut c = zenoh_config:: Config :: default ( ) ;
834+ c. set_mode ( Some ( WhatAmI :: Router ) ) . unwrap ( ) ;
835+ c. listen . endpoints . set ( vec ! [ ] ) . unwrap ( ) ;
836+ c. connect
837+ . endpoints
838+ . set ( vec ! [ ROUTER_CONNECT_ENDPOINT . parse:: <EndPoint >( ) . unwrap( ) ] )
839+ . unwrap ( ) ;
840+ c. scouting . multicast . set_enabled ( Some ( false ) ) . unwrap ( ) ;
841+ // Enable QoS for priorities and reliability support
842+ c. transport . unicast . qos . set_enabled ( true ) . unwrap ( ) ;
843+ ztimeout ! ( zenoh:: open( c) ) . unwrap ( )
844+ } ;
845+
846+ // Give some time for the connection to establish
847+ tokio:: time:: sleep ( Duration :: from_millis ( 500 ) ) . await ;
848+
849+ let reply = router1
850+ . get ( format ! ( "@/{zid1}/router?_stats=true" ) )
851+ . await
852+ . unwrap ( )
853+ . into_iter ( )
854+ . next ( ) ;
855+ assert ! ( reply. is_some( ) ) ;
856+ let binding = reply. unwrap ( ) ;
857+ let sample = binding. result ( ) . ok ( ) . unwrap ( ) ;
858+
859+ // Verify it's JSON encoded
860+ assert_eq ! ( sample. encoding( ) , & zenoh:: bytes:: Encoding :: APPLICATION_JSON ) ;
861+
862+ // Parse and verify JSON content
863+ let bytes = sample. payload ( ) . to_bytes ( ) ;
864+ let json: serde_json:: Value =
865+ serde_json:: from_slice ( & bytes) . expect ( "Failed to parse transport JSON" ) ;
866+
867+ let sessions = navigate_json_path ! ( json, "sessions" ) . 1 . as_array ( ) . unwrap ( ) ;
868+ assert_eq ! ( sessions. len( ) , 1 ) ;
869+ let rx_t_bytes = navigate_json_path ! ( sessions[ 0 ] , "stats.rx_bytes" )
870+ . 1
871+ . as_u64 ( )
872+ . unwrap ( ) ;
873+ let tx_t_bytes = navigate_json_path ! ( sessions[ 0 ] , "stats.tx_bytes" )
874+ . 1
875+ . as_u64 ( )
876+ . unwrap ( ) ;
877+ let links = navigate_json_path ! ( sessions[ 0 ] , "links" )
878+ . 1
879+ . as_array ( )
880+ . unwrap ( ) ;
881+ assert_eq ! ( links. len( ) , 1 ) ;
882+ let rx_l_bytes = navigate_json_path ! ( links[ 0 ] , "stats.rx_bytes" )
883+ . 1
884+ . as_u64 ( )
885+ . unwrap ( ) ;
886+ let tx_l_bytes = navigate_json_path ! ( links[ 0 ] , "stats.tx_bytes" )
887+ . 1
888+ . as_u64 ( )
889+ . unwrap ( ) ;
890+
891+ assert_ne ! ( rx_t_bytes, 0 ) ;
892+ assert_ne ! ( tx_t_bytes, 0 ) ;
893+ assert_ne ! ( rx_l_bytes, 0 ) ;
894+ assert_ne ! ( tx_l_bytes, 0 ) ;
895+
896+ assert_eq ! ( rx_t_bytes, rx_l_bytes) ;
897+ assert_eq ! ( tx_t_bytes, tx_l_bytes) ;
898+ }
0 commit comments