github.com/nsqio/nsq@v1.3.0/nsqd/stats_test.go (about)

     1  package nsqd
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"strconv"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/golang/snappy"
    13  	"github.com/nsqio/nsq/internal/http_api"
    14  	"github.com/nsqio/nsq/internal/test"
    15  )
    16  
    17  func TestStats(t *testing.T) {
    18  	opts := NewOptions()
    19  	opts.Logger = test.NewTestLogger(t)
    20  	tcpAddr, _, nsqd := mustStartNSQD(opts)
    21  	defer os.RemoveAll(opts.DataPath)
    22  	defer nsqd.Exit()
    23  
    24  	topicName := "test_stats" + strconv.Itoa(int(time.Now().Unix()))
    25  	topic := nsqd.GetTopic(topicName)
    26  	msg := NewMessage(topic.GenerateID(), []byte("test body"))
    27  	topic.PutMessage(msg)
    28  
    29  	accompanyTopicName := "accompany_test_stats" + strconv.Itoa(int(time.Now().Unix()))
    30  	accompanyTopic := nsqd.GetTopic(accompanyTopicName)
    31  	msg = NewMessage(accompanyTopic.GenerateID(), []byte("accompany test body"))
    32  	accompanyTopic.PutMessage(msg)
    33  
    34  	conn, err := mustConnectNSQD(tcpAddr)
    35  	test.Nil(t, err)
    36  	defer conn.Close()
    37  
    38  	identify(t, conn, nil, frameTypeResponse)
    39  	sub(t, conn, topicName, "ch")
    40  
    41  	stats := nsqd.GetStats(topicName, "ch", true).Topics
    42  	t.Logf("stats: %+v", stats)
    43  
    44  	test.Equal(t, 1, len(stats))
    45  	test.Equal(t, 1, len(stats[0].Channels))
    46  	test.Equal(t, 1, len(stats[0].Channels[0].Clients))
    47  	test.Equal(t, 1, stats[0].Channels[0].ClientCount)
    48  
    49  	stats = nsqd.GetStats(topicName, "ch", false).Topics
    50  	t.Logf("stats: %+v", stats)
    51  
    52  	test.Equal(t, 1, len(stats))
    53  	test.Equal(t, 1, len(stats[0].Channels))
    54  	test.Equal(t, 0, len(stats[0].Channels[0].Clients))
    55  	test.Equal(t, 1, stats[0].Channels[0].ClientCount)
    56  
    57  	stats = nsqd.GetStats(topicName, "none_exist_channel", false).Topics
    58  	t.Logf("stats: %+v", stats)
    59  
    60  	test.Equal(t, 0, len(stats))
    61  
    62  	stats = nsqd.GetStats("none_exist_topic", "none_exist_channel", false).Topics
    63  	t.Logf("stats: %+v", stats)
    64  
    65  	test.Equal(t, 0, len(stats))
    66  }
    67  
    68  func TestClientAttributes(t *testing.T) {
    69  	userAgent := "Test User Agent"
    70  
    71  	opts := NewOptions()
    72  	opts.Logger = test.NewTestLogger(t)
    73  	opts.LogLevel = LOG_DEBUG
    74  	opts.SnappyEnabled = true
    75  	tcpAddr, httpAddr, nsqd := mustStartNSQD(opts)
    76  	defer os.RemoveAll(opts.DataPath)
    77  	defer nsqd.Exit()
    78  
    79  	conn, err := mustConnectNSQD(tcpAddr)
    80  	test.Nil(t, err)
    81  	defer conn.Close()
    82  
    83  	data := identify(t, conn, map[string]interface{}{
    84  		"snappy":     true,
    85  		"user_agent": userAgent,
    86  	}, frameTypeResponse)
    87  	resp := struct {
    88  		Snappy    bool   `json:"snappy"`
    89  		UserAgent string `json:"user_agent"`
    90  	}{}
    91  	err = json.Unmarshal(data, &resp)
    92  	test.Nil(t, err)
    93  	test.Equal(t, true, resp.Snappy)
    94  
    95  	r := snappy.NewReader(conn)
    96  	//lint:ignore SA1019 NewWriter is deprecated by NewBufferedWriter, but we don't want to buffer
    97  	w := snappy.NewWriter(conn)
    98  	readValidate(t, r, frameTypeResponse, "OK")
    99  
   100  	topicName := "test_client_attributes" + strconv.Itoa(int(time.Now().Unix()))
   101  	sub(t, readWriter{r, w}, topicName, "ch")
   102  
   103  	var d struct {
   104  		Topics []struct {
   105  			Channels []struct {
   106  				Clients []struct {
   107  					UserAgent string `json:"user_agent"`
   108  					Snappy    bool   `json:"snappy"`
   109  				} `json:"clients"`
   110  			} `json:"channels"`
   111  		} `json:"topics"`
   112  	}
   113  
   114  	endpoint := fmt.Sprintf("http://%s/stats?format=json", httpAddr)
   115  	err = http_api.NewClient(nil, ConnectTimeout, RequestTimeout).GETV1(endpoint, &d)
   116  	test.Nil(t, err)
   117  
   118  	test.Equal(t, userAgent, d.Topics[0].Channels[0].Clients[0].UserAgent)
   119  	test.Equal(t, true, d.Topics[0].Channels[0].Clients[0].Snappy)
   120  }
   121  
   122  func TestStatsChannelLocking(t *testing.T) {
   123  	opts := NewOptions()
   124  	opts.Logger = test.NewTestLogger(t)
   125  	_, _, nsqd := mustStartNSQD(opts)
   126  	defer os.RemoveAll(opts.DataPath)
   127  	defer nsqd.Exit()
   128  
   129  	topicName := "test_channel_empty" + strconv.Itoa(int(time.Now().Unix()))
   130  	topic := nsqd.GetTopic(topicName)
   131  	channel := topic.GetChannel("channel")
   132  
   133  	var wg sync.WaitGroup
   134  
   135  	wg.Add(2)
   136  	go func() {
   137  		for i := 0; i < 25; i++ {
   138  			msg := NewMessage(topic.GenerateID(), []byte("test"))
   139  			topic.PutMessage(msg)
   140  			channel.StartInFlightTimeout(msg, 0, opts.MsgTimeout)
   141  		}
   142  		wg.Done()
   143  	}()
   144  
   145  	go func() {
   146  		for i := 0; i < 25; i++ {
   147  			nsqd.GetStats("", "", true)
   148  		}
   149  		wg.Done()
   150  	}()
   151  
   152  	wg.Wait()
   153  
   154  	stats := nsqd.GetStats(topicName, "channel", false).Topics
   155  	t.Logf("stats: %+v", stats)
   156  
   157  	test.Equal(t, 1, len(stats))
   158  	test.Equal(t, 1, len(stats[0].Channels))
   159  	test.Equal(t, 25, stats[0].Channels[0].InFlightCount)
   160  }