github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/stats/statsd/client_test.go (about)

     1  // Package statsd_test
     2  /*
     3   * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
     4   */
     5  package statsd_test
     6  
     7  import (
     8  	"fmt"
     9  	"math/rand"
    10  	"net"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/NVIDIA/aistore/stats/statsd"
    15  )
    16  
    17  var (
    18  	port     = 10001
    19  	protocol = "udp"
    20  	prefix   = "test"
    21  	self     = "localhost"
    22  )
    23  
    24  // checkMsg reads one UDP message and verifies it matches the expected string
    25  func checkMsg(t *testing.T, s *net.UDPConn, exp string) {
    26  	err := s.SetReadDeadline(time.Now().Add(3 * time.Second))
    27  	if err != nil {
    28  		t.Fatal("Failed to set server deadline", err)
    29  	}
    30  
    31  	buf := make([]byte, 256)
    32  	n, _, err := s.ReadFromUDP(buf)
    33  	if err != nil {
    34  		t.Fatal("Failed to receive", err)
    35  	}
    36  
    37  	if exp != string(buf[:n]) {
    38  		t.Fatal(fmt.Sprintf("Wrong data, exp = %s, act = %s", exp, string(buf[:n])), nil)
    39  	}
    40  }
    41  
    42  // startServer resolves the UDP address for server and starts listening on the port
    43  func startServer() (*net.UDPConn, error) {
    44  	addr, err := net.ResolveUDPAddr(protocol, fmt.Sprintf(":%d", port))
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	s, err := net.ListenUDP(protocol, addr)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return s, nil
    55  }
    56  
    57  func TestClient(t *testing.T) {
    58  	s, err := startServer()
    59  	if err != nil {
    60  		t.Fatal("Failed to start server", err)
    61  	}
    62  	defer s.Close()
    63  
    64  	c, err := statsd.New(self, port, prefix, true /* test-probe */)
    65  	if err != nil {
    66  		t.Fatal("Failed to create client", err)
    67  	}
    68  	defer c.Close()
    69  
    70  	// drain accumulated probes
    71  	buf := make([]byte, 256)
    72  	for range 10 {
    73  		_, _, err := s.ReadFromUDP(buf)
    74  		if err != nil {
    75  			t.Fatal("Failed to read probe", err)
    76  		}
    77  	}
    78  
    79  	c.Send("timer", 1,
    80  		statsd.Metric{
    81  			Type:  statsd.Timer,
    82  			Name:  "timer",
    83  			Value: 123,
    84  		})
    85  	checkMsg(t, s, "test.timer.timer:123|ms")
    86  
    87  	c.Send("three", 1,
    88  		statsd.Metric{
    89  			Type:  statsd.Timer,
    90  			Name:  "timer",
    91  			Value: 123,
    92  		},
    93  		statsd.Metric{
    94  			Type:  statsd.Counter,
    95  			Name:  "counter",
    96  			Value: 456,
    97  		},
    98  		statsd.Metric{
    99  			Type:  statsd.Gauge,
   100  			Name:  "gauge.onemore",
   101  			Value: 789,
   102  		},
   103  	)
   104  	checkMsg(t, s, "test.three.timer:123|ms\n"+
   105  		"test.three.counter:456|c\n"+
   106  		"test.three.gauge.onemore:789|g")
   107  }
   108  
   109  // server is the UDP server routine used for testing
   110  // it receives UDP requests and throw them away
   111  // stops when a message is received from the stop channel
   112  func server(c *net.UDPConn, stop <-chan bool) {
   113  	buf := make([]byte, 256)
   114  	for {
   115  		err := c.SetReadDeadline(time.Now().Add(3 * time.Second))
   116  		if err != nil {
   117  			fmt.Printf("Failed to set read deadline: %v", err)
   118  		}
   119  		_, addr, err := c.ReadFromUDP(buf)
   120  		if err, ok := err.(net.Error); ok && !err.Timeout() {
   121  			fmt.Println("Server receive failed", addr, err, ok)
   122  		}
   123  
   124  		select {
   125  		case <-stop:
   126  			return
   127  		default:
   128  		}
   129  	}
   130  }
   131  
   132  func BenchmarkSend(b *testing.B) {
   133  	s, err := startServer()
   134  	if err != nil {
   135  		b.Fatal("Failed to start server", err)
   136  	}
   137  	defer s.Close()
   138  
   139  	stop := make(chan bool)
   140  	go server(s, stop)
   141  
   142  	c, err := statsd.New(self, port, prefix, false)
   143  	if err != nil {
   144  		b.Fatal("Failed to create client", err)
   145  	}
   146  	defer c.Close()
   147  
   148  	for range b.N {
   149  		c.Send("timer", 1,
   150  			statsd.Metric{
   151  				Type:  statsd.Timer,
   152  				Name:  "test",
   153  				Value: rand.Float64(),
   154  			})
   155  	}
   156  
   157  	stop <- true
   158  }
   159  
   160  func BenchmarkSendParallel(b *testing.B) {
   161  	s, err := startServer()
   162  	if err != nil {
   163  		b.Fatal("Failed to start server", err)
   164  	}
   165  	defer s.Close()
   166  
   167  	stop := make(chan bool)
   168  	go server(s, stop)
   169  
   170  	c, err := statsd.New(self, port, prefix, false)
   171  	if err != nil {
   172  		b.Fatal("Failed to create client", err)
   173  	}
   174  	defer c.Close()
   175  
   176  	b.RunParallel(func(pb *testing.PB) {
   177  		for pb.Next() {
   178  			c.Send("timer", 1,
   179  				statsd.Metric{
   180  					Type:  statsd.Timer,
   181  					Name:  "test",
   182  					Value: rand.Float64(),
   183  				})
   184  		}
   185  	})
   186  
   187  	stop <- true
   188  }