@@ -936,16 +936,136 @@ func sendData(logf func(format string, args ...any), ctx context.Context, bytesC
936936 return nil
937937}
938938
939- func TestUserMetrics (t * testing.T ) {
939+ func TestUserMetricsByteCounters (t * testing.T ) {
940940 flakytest .Mark (t , "https://github.com/tailscale/tailscale/issues/13420" )
941941 tstest .ResourceCheck (t )
942942 ctx , cancel := context .WithTimeout (context .Background (), 120 * time .Second )
943943 defer cancel ()
944944
945- controlURL , c := startControl (t )
946- s1 , s1ip , s1PubKey := startServer (t , ctx , controlURL , "s1" )
945+ controlURL , _ := startControl (t )
946+ s1 , s1ip , _ := startServer (t , ctx , controlURL , "s1" )
947947 s2 , s2ip , _ := startServer (t , ctx , controlURL , "s2" )
948948
949+ lc1 , err := s1 .LocalClient ()
950+ if err != nil {
951+ t .Fatal (err )
952+ }
953+
954+ lc2 , err := s2 .LocalClient ()
955+ if err != nil {
956+ t .Fatal (err )
957+ }
958+
959+ // Force an update to the netmap to ensure that the metrics are up-to-date.
960+ s1 .lb .DebugForceNetmapUpdate ()
961+ s2 .lb .DebugForceNetmapUpdate ()
962+
963+ // Wait for both nodes to have a peer in their netmap.
964+ waitForCondition (t , "waiting for netmaps to contain peer" , 90 * time .Second , func () bool {
965+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
966+ defer cancel ()
967+ status1 , err := lc1 .Status (ctx )
968+ if err != nil {
969+ t .Logf ("getting status: %s" , err )
970+ return false
971+ }
972+ status2 , err := lc2 .Status (ctx )
973+ if err != nil {
974+ t .Logf ("getting status: %s" , err )
975+ return false
976+ }
977+ return len (status1 .Peers ()) > 0 && len (status2 .Peers ()) > 0
978+ })
979+
980+ // ping to make sure the connection is up.
981+ res , err := lc2 .Ping (ctx , s1ip , tailcfg .PingICMP )
982+ if err != nil {
983+ t .Fatalf ("pinging: %s" , err )
984+ }
985+ t .Logf ("ping success: %#+v" , res )
986+
987+ mustDirect (t , t .Logf , lc1 , lc2 )
988+
989+ // 1 megabytes
990+ bytesToSend := 1 * 1024 * 1024
991+
992+ // This asserts generates some traffic, it is factored out
993+ // of TestUDPConn.
994+ start := time .Now ()
995+ err = sendData (t .Logf , ctx , bytesToSend , s1 , s2 , s1ip , s2ip )
996+ if err != nil {
997+ t .Fatalf ("Failed to send packets: %v" , err )
998+ }
999+ t .Logf ("Sent %d bytes from s1 to s2 in %s" , bytesToSend , time .Since (start ).String ())
1000+
1001+ ctxLc , cancelLc := context .WithTimeout (context .Background (), 5 * time .Second )
1002+ defer cancelLc ()
1003+ metrics1 , err := lc1 .UserMetrics (ctxLc )
1004+ if err != nil {
1005+ t .Fatal (err )
1006+ }
1007+
1008+ parsedMetrics1 , err := parseMetrics (metrics1 )
1009+ if err != nil {
1010+ t .Fatal (err )
1011+ }
1012+
1013+ // Allow the metrics for the bytes sent to be off by 15%.
1014+ bytesSentTolerance := 1.15
1015+
1016+ t .Logf ("Metrics1:\n %s\n " , metrics1 )
1017+
1018+ // Verify that the amount of data recorded in bytes is higher or equal to the data sent
1019+ inboundBytes1 := parsedMetrics1 [`tailscaled_inbound_bytes_total{path="direct_ipv4"}` ]
1020+ if inboundBytes1 < float64 (bytesToSend ) {
1021+ t .Errorf (`metrics1, tailscaled_inbound_bytes_total{path="direct_ipv4"}: expected higher (or equal) than %d, got: %f` , bytesToSend , inboundBytes1 )
1022+ }
1023+
1024+ // But ensure that it is not too much higher than the data sent.
1025+ if inboundBytes1 > float64 (bytesToSend )* bytesSentTolerance {
1026+ t .Errorf (`metrics1, tailscaled_inbound_bytes_total{path="direct_ipv4"}: expected lower than %f, got: %f` , float64 (bytesToSend )* bytesSentTolerance , inboundBytes1 )
1027+ }
1028+
1029+ metrics2 , err := lc2 .UserMetrics (ctx )
1030+ if err != nil {
1031+ t .Fatal (err )
1032+ }
1033+
1034+ parsedMetrics2 , err := parseMetrics (metrics2 )
1035+ if err != nil {
1036+ t .Fatal (err )
1037+ }
1038+
1039+ t .Logf ("Metrics2:\n %s\n " , metrics2 )
1040+
1041+ // Verify that the amount of data recorded in bytes is higher or equal than the data sent.
1042+ outboundBytes2 := parsedMetrics2 [`tailscaled_outbound_bytes_total{path="direct_ipv4"}` ]
1043+ if outboundBytes2 < float64 (bytesToSend ) {
1044+ t .Errorf (`metrics2, tailscaled_outbound_bytes_total{path="direct_ipv4"}: expected higher (or equal) than %d, got: %f` , bytesToSend , outboundBytes2 )
1045+ }
1046+
1047+ // But ensure that it is not too much higher than the data sent.
1048+ if outboundBytes2 > float64 (bytesToSend )* bytesSentTolerance {
1049+ t .Errorf (`metrics2, tailscaled_outbound_bytes_total{path="direct_ipv4"}: expected lower than %f, got: %f` , float64 (bytesToSend )* bytesSentTolerance , outboundBytes2 )
1050+ }
1051+ }
1052+
1053+ func TestUserMetricsRouteGauges (t * testing.T ) {
1054+ // Windows does not seem to support or report back routes when running in
1055+ // userspace via tsnet. So, we skip this check on Windows.
1056+ // TODO(kradalby): Figure out if this is correct.
1057+ if runtime .GOOS == "windows" {
1058+ t .Skipf ("skipping on windows" )
1059+ }
1060+ flakytest .Mark (t , "https://github.com/tailscale/tailscale/issues/13420" )
1061+ tstest .ResourceCheck (t )
1062+ ctx , cancel := context .WithTimeout (context .Background (), 120 * time .Second )
1063+ defer cancel ()
1064+
1065+ controlURL , c := startControl (t )
1066+ s1 , _ , s1PubKey := startServer (t , ctx , controlURL , "s1" )
1067+ s2 , _ , _ := startServer (t , ctx , controlURL , "s2" )
1068+
9491069 s1 .lb .EditPrefs (& ipn.MaskedPrefs {
9501070 Prefs : ipn.Prefs {
9511071 AdvertiseRoutes : []netip.Prefix {
@@ -973,24 +1093,11 @@ func TestUserMetrics(t *testing.T) {
9731093 t .Fatal (err )
9741094 }
9751095
976- // ping to make sure the connection is up.
977- res , err := lc2 .Ping (ctx , s1ip , tailcfg .PingICMP )
978- if err != nil {
979- t .Fatalf ("pinging: %s" , err )
980- }
981- t .Logf ("ping success: %#+v" , res )
982-
983- ht := s1 .lb .HealthTracker ()
984- ht .SetUnhealthy (testWarnable , health.Args {"Text" : "Hello world 1" })
985-
9861096 // Force an update to the netmap to ensure that the metrics are up-to-date.
9871097 s1 .lb .DebugForceNetmapUpdate ()
9881098 s2 .lb .DebugForceNetmapUpdate ()
9891099
9901100 wantRoutes := float64 (2 )
991- if runtime .GOOS == "windows" {
992- wantRoutes = 0
993- }
9941101
9951102 // Wait for the routes to be propagated to node 1 to ensure
9961103 // that the metrics are up-to-date.
@@ -1002,31 +1109,11 @@ func TestUserMetrics(t *testing.T) {
10021109 t .Logf ("getting status: %s" , err )
10031110 return false
10041111 }
1005- if runtime .GOOS == "windows" {
1006- // Windows does not seem to support or report back routes when running in
1007- // userspace via tsnet. So, we skip this check on Windows.
1008- // TODO(kradalby): Figure out if this is correct.
1009- return true
1010- }
10111112 // Wait for the primary routes to reach our desired routes, which is wantRoutes + 1, because
10121113 // the PrimaryRoutes list will contain a exit node route, which the metric does not count.
10131114 return status1 .Self .PrimaryRoutes != nil && status1 .Self .PrimaryRoutes .Len () == int (wantRoutes )+ 1
10141115 })
10151116
1016- mustDirect (t , t .Logf , lc1 , lc2 )
1017-
1018- // 1 megabytes
1019- bytesToSend := 1 * 1024 * 1024
1020-
1021- // This asserts generates some traffic, it is factored out
1022- // of TestUDPConn.
1023- start := time .Now ()
1024- err = sendData (t .Logf , ctx , bytesToSend , s1 , s2 , s1ip , s2ip )
1025- if err != nil {
1026- t .Fatalf ("Failed to send packets: %v" , err )
1027- }
1028- t .Logf ("Sent %d bytes from s1 to s2 in %s" , bytesToSend , time .Since (start ).String ())
1029-
10301117 ctxLc , cancelLc := context .WithTimeout (context .Background (), 5 * time .Second )
10311118 defer cancelLc ()
10321119 metrics1 , err := lc1 .UserMetrics (ctxLc )
@@ -1039,9 +1126,6 @@ func TestUserMetrics(t *testing.T) {
10391126 t .Fatal (err )
10401127 }
10411128
1042- // Allow the metrics for the bytes sent to be off by 15%.
1043- bytesSentTolerance := 1.15
1044-
10451129 t .Logf ("Metrics1:\n %s\n " , metrics1 )
10461130
10471131 // The node is advertising 4 routes:
@@ -1059,17 +1143,6 @@ func TestUserMetrics(t *testing.T) {
10591143 t .Errorf ("metrics1, tailscaled_approved_routes: got %v, want %v" , got , want )
10601144 }
10611145
1062- // Verify that the amount of data recorded in bytes is higher or equal to the data sent
1063- inboundBytes1 := parsedMetrics1 [`tailscaled_inbound_bytes_total{path="direct_ipv4"}` ]
1064- if inboundBytes1 < float64 (bytesToSend ) {
1065- t .Errorf (`metrics1, tailscaled_inbound_bytes_total{path="direct_ipv4"}: expected higher (or equal) than %d, got: %f` , bytesToSend , inboundBytes1 )
1066- }
1067-
1068- // But ensure that it is not too much higher than the data sent.
1069- if inboundBytes1 > float64 (bytesToSend )* bytesSentTolerance {
1070- t .Errorf (`metrics1, tailscaled_inbound_bytes_total{path="direct_ipv4"}: expected lower than %f, got: %f` , float64 (bytesToSend )* bytesSentTolerance , inboundBytes1 )
1071- }
1072-
10731146 metrics2 , err := lc2 .UserMetrics (ctx )
10741147 if err != nil {
10751148 t .Fatal (err )
@@ -1091,17 +1164,6 @@ func TestUserMetrics(t *testing.T) {
10911164 if got , want := parsedMetrics2 ["tailscaled_approved_routes" ], 0.0 ; got != want {
10921165 t .Errorf ("metrics2, tailscaled_approved_routes: got %v, want %v" , got , want )
10931166 }
1094-
1095- // Verify that the amount of data recorded in bytes is higher or equal than the data sent.
1096- outboundBytes2 := parsedMetrics2 [`tailscaled_outbound_bytes_total{path="direct_ipv4"}` ]
1097- if outboundBytes2 < float64 (bytesToSend ) {
1098- t .Errorf (`metrics2, tailscaled_outbound_bytes_total{path="direct_ipv4"}: expected higher (or equal) than %d, got: %f` , bytesToSend , outboundBytes2 )
1099- }
1100-
1101- // But ensure that it is not too much higher than the data sent.
1102- if outboundBytes2 > float64 (bytesToSend )* bytesSentTolerance {
1103- t .Errorf (`metrics2, tailscaled_outbound_bytes_total{path="direct_ipv4"}: expected lower than %f, got: %f` , float64 (bytesToSend )* bytesSentTolerance , outboundBytes2 )
1104- }
11051167}
11061168
11071169func waitForCondition (t * testing.T , msg string , waitTime time.Duration , f func () bool ) {
0 commit comments