github.com/nsqio/nsq@v1.3.0/nsqd/topic_test.go (about) 1 package nsqd 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "net/http" 8 "os" 9 "runtime" 10 "strconv" 11 "testing" 12 "time" 13 14 "github.com/nsqio/nsq/internal/test" 15 ) 16 17 func TestGetTopic(t *testing.T) { 18 opts := NewOptions() 19 opts.Logger = test.NewTestLogger(t) 20 _, _, nsqd := mustStartNSQD(opts) 21 defer os.RemoveAll(opts.DataPath) 22 defer nsqd.Exit() 23 24 topic1 := nsqd.GetTopic("test") 25 test.NotNil(t, topic1) 26 test.Equal(t, "test", topic1.name) 27 28 topic2 := nsqd.GetTopic("test") 29 test.Equal(t, topic1, topic2) 30 31 topic3 := nsqd.GetTopic("test2") 32 test.Equal(t, "test2", topic3.name) 33 test.NotEqual(t, topic2, topic3) 34 } 35 36 func TestGetChannel(t *testing.T) { 37 opts := NewOptions() 38 opts.Logger = test.NewTestLogger(t) 39 _, _, nsqd := mustStartNSQD(opts) 40 defer os.RemoveAll(opts.DataPath) 41 defer nsqd.Exit() 42 43 topic := nsqd.GetTopic("test") 44 45 channel1 := topic.GetChannel("ch1") 46 test.NotNil(t, channel1) 47 test.Equal(t, "ch1", channel1.name) 48 49 channel2 := topic.GetChannel("ch2") 50 51 test.Equal(t, channel1, topic.channelMap["ch1"]) 52 test.Equal(t, channel2, topic.channelMap["ch2"]) 53 } 54 55 type errorBackendQueue struct{} 56 57 func (d *errorBackendQueue) Put([]byte) error { return errors.New("never gonna happen") } 58 func (d *errorBackendQueue) ReadChan() <-chan []byte { return nil } 59 func (d *errorBackendQueue) Close() error { return nil } 60 func (d *errorBackendQueue) Delete() error { return nil } 61 func (d *errorBackendQueue) Depth() int64 { return 0 } 62 func (d *errorBackendQueue) Empty() error { return nil } 63 64 type errorRecoveredBackendQueue struct{ errorBackendQueue } 65 66 func (d *errorRecoveredBackendQueue) Put([]byte) error { return nil } 67 68 func TestHealth(t *testing.T) { 69 opts := NewOptions() 70 opts.Logger = test.NewTestLogger(t) 71 opts.MemQueueSize = 2 72 _, httpAddr, nsqd := mustStartNSQD(opts) 73 defer os.RemoveAll(opts.DataPath) 74 defer nsqd.Exit() 75 76 topic := nsqd.GetTopic("test") 77 topic.backend = &errorBackendQueue{} 78 79 msg := NewMessage(topic.GenerateID(), make([]byte, 100)) 80 err := topic.PutMessage(msg) 81 test.Nil(t, err) 82 83 msg = NewMessage(topic.GenerateID(), make([]byte, 100)) 84 err = topic.PutMessages([]*Message{msg}) 85 test.Nil(t, err) 86 87 msg = NewMessage(topic.GenerateID(), make([]byte, 100)) 88 err = topic.PutMessage(msg) 89 test.NotNil(t, err) 90 91 msg = NewMessage(topic.GenerateID(), make([]byte, 100)) 92 err = topic.PutMessages([]*Message{msg}) 93 test.NotNil(t, err) 94 95 url := fmt.Sprintf("http://%s/ping", httpAddr) 96 resp, err := http.Get(url) 97 test.Nil(t, err) 98 test.Equal(t, 500, resp.StatusCode) 99 body, _ := io.ReadAll(resp.Body) 100 resp.Body.Close() 101 test.Equal(t, "NOK - never gonna happen", string(body)) 102 103 topic.backend = &errorRecoveredBackendQueue{} 104 105 msg = NewMessage(topic.GenerateID(), make([]byte, 100)) 106 err = topic.PutMessages([]*Message{msg}) 107 test.Nil(t, err) 108 109 resp, err = http.Get(url) 110 test.Nil(t, err) 111 test.Equal(t, 200, resp.StatusCode) 112 body, _ = io.ReadAll(resp.Body) 113 resp.Body.Close() 114 test.Equal(t, "OK", string(body)) 115 } 116 117 func TestDeletes(t *testing.T) { 118 opts := NewOptions() 119 opts.Logger = test.NewTestLogger(t) 120 _, _, nsqd := mustStartNSQD(opts) 121 defer os.RemoveAll(opts.DataPath) 122 defer nsqd.Exit() 123 124 topic := nsqd.GetTopic("test") 125 126 channel1 := topic.GetChannel("ch1") 127 test.NotNil(t, channel1) 128 129 err := topic.DeleteExistingChannel("ch1") 130 test.Nil(t, err) 131 test.Equal(t, 0, len(topic.channelMap)) 132 133 channel2 := topic.GetChannel("ch2") 134 test.NotNil(t, channel2) 135 136 err = nsqd.DeleteExistingTopic("test") 137 test.Nil(t, err) 138 test.Equal(t, 0, len(topic.channelMap)) 139 test.Equal(t, 0, len(nsqd.topicMap)) 140 } 141 142 func TestDeleteLast(t *testing.T) { 143 opts := NewOptions() 144 opts.Logger = test.NewTestLogger(t) 145 _, _, nsqd := mustStartNSQD(opts) 146 defer os.RemoveAll(opts.DataPath) 147 defer nsqd.Exit() 148 149 topic := nsqd.GetTopic("test") 150 151 channel1 := topic.GetChannel("ch1") 152 test.NotNil(t, channel1) 153 154 err := topic.DeleteExistingChannel("ch1") 155 test.Nil(t, err) 156 test.Equal(t, 0, len(topic.channelMap)) 157 158 msg := NewMessage(topic.GenerateID(), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaa")) 159 err = topic.PutMessage(msg) 160 time.Sleep(100 * time.Millisecond) 161 test.Nil(t, err) 162 test.Equal(t, int64(1), topic.Depth()) 163 } 164 165 func TestPause(t *testing.T) { 166 opts := NewOptions() 167 opts.Logger = test.NewTestLogger(t) 168 _, _, nsqd := mustStartNSQD(opts) 169 defer os.RemoveAll(opts.DataPath) 170 defer nsqd.Exit() 171 172 topicName := "test_topic_pause" + strconv.Itoa(int(time.Now().Unix())) 173 topic := nsqd.GetTopic(topicName) 174 err := topic.Pause() 175 test.Nil(t, err) 176 177 channel := topic.GetChannel("ch1") 178 test.NotNil(t, channel) 179 180 msg := NewMessage(topic.GenerateID(), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaa")) 181 err = topic.PutMessage(msg) 182 test.Nil(t, err) 183 184 time.Sleep(15 * time.Millisecond) 185 186 test.Equal(t, int64(1), topic.Depth()) 187 test.Equal(t, int64(0), channel.Depth()) 188 189 err = topic.UnPause() 190 test.Nil(t, err) 191 192 time.Sleep(15 * time.Millisecond) 193 194 test.Equal(t, int64(0), topic.Depth()) 195 test.Equal(t, int64(1), channel.Depth()) 196 } 197 198 func BenchmarkTopicPut(b *testing.B) { 199 b.StopTimer() 200 topicName := "bench_topic_put" + strconv.Itoa(b.N) 201 opts := NewOptions() 202 opts.Logger = test.NewTestLogger(b) 203 opts.MemQueueSize = int64(b.N) 204 _, _, nsqd := mustStartNSQD(opts) 205 defer os.RemoveAll(opts.DataPath) 206 defer nsqd.Exit() 207 b.StartTimer() 208 209 for i := 0; i <= b.N; i++ { 210 topic := nsqd.GetTopic(topicName) 211 msg := NewMessage(topic.GenerateID(), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaa")) 212 topic.PutMessage(msg) 213 } 214 } 215 216 func BenchmarkTopicToChannelPut(b *testing.B) { 217 b.StopTimer() 218 topicName := "bench_topic_to_channel_put" + strconv.Itoa(b.N) 219 channelName := "bench" 220 opts := NewOptions() 221 opts.Logger = test.NewTestLogger(b) 222 opts.MemQueueSize = int64(b.N) 223 _, _, nsqd := mustStartNSQD(opts) 224 defer os.RemoveAll(opts.DataPath) 225 defer nsqd.Exit() 226 channel := nsqd.GetTopic(topicName).GetChannel(channelName) 227 b.StartTimer() 228 229 for i := 0; i <= b.N; i++ { 230 topic := nsqd.GetTopic(topicName) 231 msg := NewMessage(topic.GenerateID(), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaa")) 232 topic.PutMessage(msg) 233 } 234 235 for { 236 if len(channel.memoryMsgChan) == b.N { 237 break 238 } 239 runtime.Gosched() 240 } 241 }