Test to the best of our ability
This commit is contained in:
		
							
								
								
									
										171
									
								
								broker/mqtt/mqtt_mock.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								broker/mqtt/mqtt_mock.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | |||||||
|  | package mqtt | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math/rand" | ||||||
|  | 	"sync" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/eclipse/paho.mqtt.golang" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type mockClient struct { | ||||||
|  | 	sync.Mutex | ||||||
|  | 	connected bool | ||||||
|  | 	exit      chan bool | ||||||
|  |  | ||||||
|  | 	subs map[string][]mqtt.MessageHandler | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type mockMessage struct { | ||||||
|  | 	id       uint16 | ||||||
|  | 	topic    string | ||||||
|  | 	qos      byte | ||||||
|  | 	retained bool | ||||||
|  | 	payload  interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	_ mqtt.Client  = newMockClient() | ||||||
|  | 	_ mqtt.Message = newMockMessage("mock", 0, false, nil) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	rand.Seed(time.Now().UnixNano()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newMockClient() mqtt.Client { | ||||||
|  | 	return &mockClient{ | ||||||
|  | 		subs: make(map[string][]mqtt.MessageHandler), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newMockMessage(topic string, qos byte, retained bool, payload interface{}) mqtt.Message { | ||||||
|  | 	return &mockMessage{ | ||||||
|  | 		id:       uint16(rand.Int()), | ||||||
|  | 		topic:    topic, | ||||||
|  | 		qos:      qos, | ||||||
|  | 		retained: retained, | ||||||
|  | 		payload:  payload, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) Duplicate() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) Qos() byte { | ||||||
|  | 	return m.qos | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) Retained() bool { | ||||||
|  | 	return m.retained | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) Topic() string { | ||||||
|  | 	return m.topic | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) MessageID() uint16 { | ||||||
|  | 	return m.id | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockMessage) Payload() []byte { | ||||||
|  | 	return m.payload.([]byte) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) IsConnected() bool { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  | 	return m.connected | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) Connect() mqtt.Token { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if m.connected { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m.connected = true | ||||||
|  | 	m.exit = make(chan bool) | ||||||
|  | 	return &mqtt.ConnectToken{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) Disconnect(uint) { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if !m.connected { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m.connected = false | ||||||
|  |  | ||||||
|  | 	select { | ||||||
|  | 	case <-m.exit: | ||||||
|  | 		return | ||||||
|  | 	default: | ||||||
|  | 		close(m.exit) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) Publish(topic string, qos byte, retained bool, payload interface{}) mqtt.Token { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if !m.connected { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	msg := newMockMessage(topic, qos, retained, payload) | ||||||
|  |  | ||||||
|  | 	for _, sub := range m.subs[topic] { | ||||||
|  | 		sub(m, msg) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &mqtt.PublishToken{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) Subscribe(topic string, qos byte, h mqtt.MessageHandler) mqtt.Token { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if !m.connected { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m.subs[topic] = append(m.subs[topic], h) | ||||||
|  |  | ||||||
|  | 	return &mqtt.SubscribeToken{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) SubscribeMultiple(topics map[string]byte, h mqtt.MessageHandler) mqtt.Token { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if !m.connected { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for topic, _ := range topics { | ||||||
|  | 		m.subs[topic] = append(m.subs[topic], h) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &mqtt.SubscribeToken{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *mockClient) Unsubscribe(topics ...string) mqtt.Token { | ||||||
|  | 	m.Lock() | ||||||
|  | 	defer m.Unlock() | ||||||
|  |  | ||||||
|  | 	if !m.connected { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, topic := range topics { | ||||||
|  | 		delete(m.subs, topic) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &mqtt.UnsubscribeToken{} | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								broker/mqtt/mqtt_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								broker/mqtt/mqtt_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | package mqtt | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/eclipse/paho.mqtt.golang" | ||||||
|  | 	"github.com/micro/go-micro/broker" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMQTTMock(t *testing.T) { | ||||||
|  | 	c := newMockClient() | ||||||
|  |  | ||||||
|  | 	if tk := c.Connect(); tk == nil { | ||||||
|  | 		t.Fatal("got nil token") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if tk := c.Subscribe("mock", 0, func(cm mqtt.Client, m mqtt.Message) { | ||||||
|  | 		t.Logf("Received payload %+v", string(m.Payload())) | ||||||
|  | 	}); tk == nil { | ||||||
|  | 		t.Fatal("got nil token") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if tk := c.Publish("mock", 0, false, []byte(`hello world`)); tk == nil { | ||||||
|  | 		t.Fatal("got nil token") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if tk := c.Unsubscribe("mock"); tk == nil { | ||||||
|  | 		t.Fatal("got nil token") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	c.Disconnect(0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestMQTTHandler(t *testing.T) { | ||||||
|  | 	p := &mqttPub{ | ||||||
|  | 		msg: newMockMessage("mock", 0, false, []byte(`hello`)), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if p.Topic() != "mock" { | ||||||
|  | 		t.Fatal("Expected topic mock got", p.Topic()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if string(p.Message().Body) != "hello" { | ||||||
|  | 		t.Fatal("Expected `hello` message got %s", string(p.Message().Body)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	s := &mqttSub{ | ||||||
|  | 		topic:  "mock", | ||||||
|  | 		client: newMockClient(), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	s.client.Connect() | ||||||
|  |  | ||||||
|  | 	if s.Topic() != "mock" { | ||||||
|  | 		t.Fatal("Expected topic mock got", s.Topic()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := s.Unsubscribe(); err != nil { | ||||||
|  | 		t.Fatal("Error unsubscribing", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	s.client.Disconnect(0) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestMQTT(t *testing.T) { | ||||||
|  | 	b := NewBroker() | ||||||
|  |  | ||||||
|  | 	if err := b.Init(); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// use mock client | ||||||
|  | 	b.(*mqttBroker).client = newMockClient() | ||||||
|  |  | ||||||
|  | 	if tk := b.(*mqttBroker).client.Connect(); tk == nil { | ||||||
|  | 		t.Fatal("got nil token") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := b.Publish("mock", &broker.Message{Body: []byte(`hello`)}); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := b.Disconnect(); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	b.(*mqttBroker).client.Disconnect(0) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user