Skip to content

Commit

Permalink
Mqtt: fix publishing built-in struct types, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed Dec 2, 2023
1 parent 9fc5faa commit 66143c2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
19 changes: 13 additions & 6 deletions server/mqtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ var deprecatedTopics = []string{

// MQTT is the MQTT server. It uses the MQTT client for publishing.
type MQTT struct {
log *util.Logger
Handler *mqtt.Client
root string
log *util.Logger
Handler *mqtt.Client
root string
publisher func(topic string, retained bool, payload string)
}

// NewMQTT creates MQTT server
func NewMQTT(root string) *MQTT {
return &MQTT{
m := &MQTT{
log: util.NewLogger("mqtt"),
Handler: mqtt.Instance,
root: root,
}
m.publisher = m.publishString
return m
}

func (m *MQTT) encode(v interface{}) string {
Expand Down Expand Up @@ -65,7 +68,7 @@ func (m *MQTT) encode(v interface{}) string {
}

func (m *MQTT) publishComplex(topic string, retained bool, payload interface{}) {
if payload == nil {
if _, ok := payload.(fmt.Stringer); ok || payload == nil {
m.publishSingleValue(topic, retained, payload)
return
}
Expand Down Expand Up @@ -105,11 +108,15 @@ func (m *MQTT) publishComplex(topic string, retained bool, payload interface{})
}
}

func (m *MQTT) publishSingleValue(topic string, retained bool, payload interface{}) {
func (m *MQTT) publishString(topic string, retained bool, payload string) {
token := m.Handler.Client.Publish(topic, m.Handler.Qos, retained, m.encode(payload))
go m.Handler.WaitForToken("send", topic, token)
}

func (m *MQTT) publishSingleValue(topic string, retained bool, payload interface{}) {
m.publisher(topic, retained, m.encode(payload))
}

func (m *MQTT) publish(topic string, retained bool, payload interface{}) {
// publish phase values
if slice, ok := payload.([]float64); ok && len(slice) == 3 {
Expand Down
42 changes: 42 additions & 0 deletions server/mqtt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,55 @@ package server

import (
"math"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMqttNaNInf(t *testing.T) {
m := &MQTT{}
assert.Equal(t, "NaN", m.encode(math.NaN()), "NaN not encoded as string")
assert.Equal(t, "+Inf", m.encode(math.Inf(0)), "Inf not encoded as string")
}

func TestPublishTypes(t *testing.T) {
var topics, payloads []string

reset := func() {
topics = topics[:0]
payloads = payloads[:0]
}

m := &MQTT{
publisher: func(topic string, retained bool, payload string) {
topics = append(topics, topic)
payloads = append(payloads, payload)
},
}

now := time.Now()
m.publish("test", false, now)
require.Len(t, topics, 1)
assert.Equal(t, strconv.FormatInt(now.Unix(), 10), payloads[0], "time not encoded as unix timestamp")
reset()

m.publish("test", false, struct {
Foo string
}{
Foo: "bar",
})
require.Len(t, topics, 1)
assert.Equal(t, `test/foo`, topics[0], "struct mismatch")
assert.Equal(t, `bar`, payloads[0], "struct mismatch")
reset()

slice := []int{10, 20}
m.publish("test", false, slice)
require.Len(t, topics, 3)
assert.Equal(t, []string{`test`, `test/1`, `test/2`}, topics, "slice mismatch")
assert.Equal(t, []string{`2`, `10`, `20`}, payloads, "slice mismatch")
reset()
}

0 comments on commit 66143c2

Please sign in to comment.