github.com/psiphon-inc/goarista@v0.0.0-20160825065156-d002785f4c67/kafka/producer/producer_test.go (about) 1 // Copyright (C) 2016 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package producer 6 7 import ( 8 "encoding/json" 9 "strings" 10 "sync" 11 "testing" 12 13 "github.com/Shopify/sarama" 14 "github.com/aristanetworks/goarista/kafka/openconfig" 15 pb "github.com/aristanetworks/goarista/openconfig" 16 "github.com/aristanetworks/goarista/test" 17 "github.com/golang/protobuf/proto" 18 ) 19 20 type mockAsyncProducer struct { 21 input chan *sarama.ProducerMessage 22 successes chan *sarama.ProducerMessage 23 errors chan *sarama.ProducerError 24 } 25 26 func newMockAsyncProducer() *mockAsyncProducer { 27 return &mockAsyncProducer{ 28 input: make(chan *sarama.ProducerMessage), 29 successes: make(chan *sarama.ProducerMessage), 30 errors: make(chan *sarama.ProducerError)} 31 } 32 33 func (p *mockAsyncProducer) AsyncClose() { 34 panic("Not implemented") 35 } 36 37 func (p *mockAsyncProducer) Close() error { 38 close(p.successes) 39 close(p.errors) 40 return nil 41 } 42 43 func (p *mockAsyncProducer) Input() chan<- *sarama.ProducerMessage { 44 return p.input 45 } 46 47 func (p *mockAsyncProducer) Successes() <-chan *sarama.ProducerMessage { 48 return p.successes 49 } 50 51 func (p *mockAsyncProducer) Errors() <-chan *sarama.ProducerError { 52 return p.errors 53 } 54 55 func newPath(path string) *pb.Path { 56 if path == "" { 57 return nil 58 } 59 return &pb.Path{Element: strings.Split(path, "/")} 60 } 61 62 func TestKafkaProducer(t *testing.T) { 63 mock := newMockAsyncProducer() 64 toDB := make(chan proto.Message) 65 topic := "occlient" 66 systemID := "Foobar" 67 toDBProducer := &producer{ 68 notifsChan: toDB, 69 kafkaProducer: mock, 70 topic: topic, 71 key: sarama.StringEncoder(systemID), 72 encoder: openconfig.ElasticsearchMessageEncoder, 73 done: make(chan struct{}), 74 wg: sync.WaitGroup{}, 75 } 76 77 go toDBProducer.Run() 78 79 response := &pb.SubscribeResponse{ 80 Response: &pb.SubscribeResponse_Update{ 81 Update: &pb.Notification{ 82 Timestamp: 0, 83 Prefix: newPath("/foo/bar"), 84 Update: []*pb.Update{}, 85 }, 86 }, 87 } 88 document := map[string]interface{}{ 89 "": map[string]interface{}{ 90 "foo": map[string]interface{}{ 91 "bar": map[string]interface{}{}, 92 }, 93 }, 94 } 95 96 toDB <- response 97 98 kafkaMessage := <-mock.input 99 if kafkaMessage.Topic != topic { 100 t.Errorf("Unexpected Topic: %s, expecting %s", kafkaMessage.Topic, topic) 101 } 102 key, err := kafkaMessage.Key.Encode() 103 if err != nil { 104 t.Fatalf("Error encoding key: %s", err) 105 } 106 if string(key) != systemID { 107 t.Errorf("Kafka message didn't have expected key: %s, expecting %s", string(key), systemID) 108 } 109 110 valueBytes, err := kafkaMessage.Value.Encode() 111 if err != nil { 112 t.Fatalf("Error encoding value: %s", err) 113 } 114 var result interface{} 115 err = json.Unmarshal(valueBytes, &result) 116 if err != nil { 117 t.Errorf("Error decoding into JSON: %s", err) 118 } 119 if !test.DeepEqual(document[""], result.(map[string]interface{})[""]) { 120 t.Errorf("Protobuf sent from Kafka Producer does not match original.\nOriginal: %v\nNew:%v", 121 document, result) 122 } 123 124 toDBProducer.Stop() 125 }