github.com/Goboolean/common@v0.0.0-20231130153141-cb54596b217d/pkg/kafka/consumer_test.go (about) 1 package kafka_test 2 3 import ( 4 "context" 5 "os" 6 "testing" 7 "time" 8 9 model_latest "github.com/Goboolean/common/api/kafka/model.latest" 10 "github.com/Goboolean/common/pkg/kafka" 11 "github.com/Goboolean/common/pkg/resolver" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 type SubscribeListenerImpl struct { 16 channel chan *model_latest.Event 17 } 18 19 func newSubscribeListenerImpl(ch chan *model_latest.Event) *SubscribeListenerImpl { 20 return &SubscribeListenerImpl{ 21 channel: ch, 22 } 23 } 24 25 func (s *SubscribeListenerImpl) OnReceiveMessage(ctx context.Context, msg *model_latest.Event) error { 26 s.channel <- msg 27 return nil 28 } 29 30 func SetupConsumer(ch chan *model_latest.Event) *kafka.Consumer[*model_latest.Event] { 31 32 c, err := kafka.NewConsumer[*model_latest.Event](&resolver.ConfigMap{ 33 "BOOTSTRAP_HOST": os.Getenv("KAFKA_BOOTSTRAP_HOST"), 34 "GROUP_ID": "TEST_GROUP", 35 "PROCESSOR_COUNT": 2, 36 }, newSubscribeListenerImpl(ch)) 37 if err != nil { 38 panic(err) 39 } 40 return c 41 } 42 43 func SetupConsumerWithRegistry(ch chan *model_latest.Event) *kafka.Consumer[*model_latest.Event] { 44 45 c, err := kafka.NewConsumer[*model_latest.Event](&resolver.ConfigMap{ 46 "BOOTSTRAP_HOST": os.Getenv("KAFKA_BOOTSTRAP_HOST"), 47 "REGISTRY_HOST": os.Getenv("KAFKA_REGISTRY_HOST"), 48 "GROUP_ID": "TEST_GROUP", 49 "PROCESSOR_COUNT": 2, 50 }, newSubscribeListenerImpl(ch)) 51 if err != nil { 52 panic(err) 53 } 54 return c 55 } 56 57 func SetupConsumerWithGroup(ch chan *model_latest.Event, group string) *kafka.Consumer[*model_latest.Event] { 58 59 c, err := kafka.NewConsumer[*model_latest.Event](&resolver.ConfigMap{ 60 "BOOTSTRAP_HOST": os.Getenv("KAFKA_BOOTSTRAP_HOST"), 61 "GROUP_ID": group, 62 "PROCESSOR_COUNT": 2, 63 }, newSubscribeListenerImpl(ch)) 64 if err != nil { 65 panic(err) 66 } 67 return c 68 } 69 70 func TeardownConsumer(c *kafka.Consumer[*model_latest.Event]) { 71 mutex.Lock() 72 defer mutex.Unlock() 73 c.Close() 74 } 75 76 func Test_Consumer(t *testing.T) { 77 78 const topic = "test-consumer" 79 var event = &model_latest.Event{ 80 EventUuid: "test-uuid", 81 } 82 83 var channel = make(chan *model_latest.Event, 10) 84 85 c := SetupConsumer(channel) 86 defer TeardownConsumer(c) 87 p := SetupProducer() 88 defer TeardownProducer(p) 89 90 t.Run("Ping", func(t *testing.T) { 91 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 92 defer cancel() 93 94 err := c.Ping(ctx) 95 assert.NoError(t, err) 96 }) 97 98 t.Run("Subscribe", func(t *testing.T) { 99 err := c.Subscribe(topic, event.ProtoReflect().Type()) 100 assert.NoError(t, err) 101 }) 102 103 t.Run("ConsumeMessage", func(t *testing.T) { 104 err := p.Produce(topic, event) 105 assert.NoError(t, err) 106 107 ctx, cancel := context.WithTimeout(context.Background(), time.Second*7) 108 defer cancel() 109 110 select { 111 case <-ctx.Done(): 112 assert.Fail(t, "failed to receive all message before timeout") 113 return 114 case <-channel: 115 break 116 } 117 }) 118 } 119 120 func Test_ConsumerWithRegistry(t *testing.T) { 121 t.Skip("Skip this test because of the registry is not ready.") 122 123 const topic = "test-consumer-with-registry" 124 var event = &model_latest.Event{} 125 126 var channel = make(chan *model_latest.Event, 10) 127 128 c := SetupConsumer(channel) 129 defer TeardownConsumer(c) 130 p := SetupProducer() 131 defer TeardownProducer(p) 132 133 t.Run("Ping", func(t *testing.T) { 134 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 135 defer cancel() 136 137 err := c.Ping(ctx) 138 assert.NoError(t, err) 139 }) 140 141 t.Run("Subscribe", func(t *testing.T) { 142 err := c.Subscribe(topic, event.ProtoReflect().Type()) 143 assert.NoError(t, err) 144 }) 145 146 t.Run("ConsumeMessage", func(t *testing.T) { 147 _, err := p.Register(topic, event) 148 assert.NoError(t, err) 149 150 err = p.Produce(topic, event) 151 assert.NoError(t, err) 152 153 ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 154 defer cancel() 155 156 select { 157 case <-ctx.Done(): 158 assert.Fail(t, "failed to receive all message before timeout") 159 return 160 case <-channel: 161 break 162 } 163 }) 164 } 165 166 func Test_ConsumeSameGroup(t *testing.T) { 167 168 const topic = "test-consumer-same-group" 169 const count = 3 170 var event = &model_latest.Event{EventUuid: "test-uuid"} 171 172 var ch1 = make(chan *model_latest.Event, 10) 173 var ch2 = make(chan *model_latest.Event, 10) 174 175 c1 := SetupConsumerWithGroup(ch1, "TEST_GROUP") 176 defer TeardownConsumer(c1) 177 c2 := SetupConsumerWithGroup(ch2, "TEST_GROUP") 178 defer TeardownConsumer(c2) 179 180 p := SetupProducer() 181 defer TeardownProducer(p) 182 183 t.Run("Subscribe", func(t *testing.T) { 184 err := c1.Subscribe(topic, event.ProtoReflect().Type()) 185 assert.NoError(t, err) 186 187 err = c2.Subscribe(topic, event.ProtoReflect().Type()) 188 assert.NoError(t, err) 189 }) 190 191 t.Run("ConsumeMessage", func(t *testing.T) { 192 for i := 0; i < count; i++ { 193 err := p.Produce(topic, event) 194 assert.NoError(t, err) 195 } 196 197 ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 198 defer cancel() 199 200 <-ctx.Done() 201 assert.Equal(t, count, len(ch1)+len(ch2)) 202 }) 203 } 204 205 func Test_ConsumeDifferentGroup(t *testing.T) { 206 207 const topic = "test-consumer-different-group" 208 const count = 3 209 var event = &model_latest.Event{EventUuid: "test-uuid"} 210 211 var ch_a = make(chan *model_latest.Event, 10) 212 var ch_b = make(chan *model_latest.Event, 10) 213 214 c_a := SetupConsumerWithGroup(ch_a, "TEST_GROUP_A") 215 defer TeardownConsumer(c_a) 216 c_b := SetupConsumerWithGroup(ch_b, "TEST_GROUP_B") 217 defer TeardownConsumer(c_b) 218 219 p := SetupProducer() 220 defer TeardownProducer(p) 221 222 t.Run("Subscribe", func(t *testing.T) { 223 err := c_a.Subscribe(topic, event.ProtoReflect().Type()) 224 assert.NoError(t, err) 225 226 err = c_b.Subscribe(topic, event.ProtoReflect().Type()) 227 assert.NoError(t, err) 228 }) 229 230 t.Run("ConsumeMessage", func(t *testing.T) { 231 for i := 0; i < count; i++ { 232 err := p.Produce(topic, event) 233 assert.NoError(t, err) 234 } 235 236 ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 237 defer cancel() 238 239 <-ctx.Done() 240 assert.Equal(t, count, len(ch_a)) 241 assert.Equal(t, count, len(ch_b)) 242 }) 243 }