diff --git a/Dockerfile b/Dockerfile index 973432e..8fa1feb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM golang:1.11 -WORKDIR /go/src/gosrc.io/xmpp +WORKDIR /xmpp RUN curl -o codecov.sh -s https://codecov.io/bash && chmod +x codecov.sh COPY . ./ -RUN go get -t ./... +# RUN go get -t ./... diff --git a/check_cert.go b/check_cert.go index b23b6bb..6190d96 100644 --- a/check_cert.go +++ b/check_cert.go @@ -1,4 +1,4 @@ -package xmpp +package xmpp // import "gosrc.io/xmpp" import ( "crypto/tls" diff --git a/client.go b/client.go index 2983b81..f6f5be2 100644 --- a/client.go +++ b/client.go @@ -119,7 +119,7 @@ func (c *Client) Connect() (*Session, error) { var try = 0 var success bool c.Metrics = initMetrics() - for try <= c.config.Retry || !success { + for try <= c.config.Retry && !success { if tcpconn, err = net.DialTimeout("tcp", c.config.Address, time.Duration(c.config.ConnectTimeout)*time.Second); err == nil { c.Metrics.setConnectTime() success = true diff --git a/cmd/xmpp-check/README.md b/cmd/xmpp-check/README.md new file mode 100644 index 0000000..e2d5b3e --- /dev/null +++ b/cmd/xmpp-check/README.md @@ -0,0 +1,28 @@ +# XMPP Check + +XMPP check is a tool to check TLS certificate on a remote server. + +## Installation + +``` +$ go get -u gosrc.io/xmpp/cmd/xmpp-check +``` + +## Usage + +If you server is on standard port and XMPP domains matches the hostname you can simply use: + +``` +$ xmpp-check myhost.net +2019/05/16 16:04:36 All checks passed +``` + +You can also pass the port and the XMPP domain if different from the server hostname: + +``` +$ xmpp-check myhost.net:5222 xmppdomain.net +2019/05/16 16:05:21 All checks passed +``` + +Error code will be non-zero in case of error. You can thus use it directly with your usual +monitoring scripts. diff --git a/iq_test.go b/iq_test.go index 959a602..f78456b 100644 --- a/iq_test.go +++ b/iq_test.go @@ -1,4 +1,4 @@ -package xmpp // import "gosrc.io/xmpp" +package xmpp_test // import "gosrc.io/xmpp" import ( "encoding/xml" @@ -6,20 +6,22 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "gosrc.io/xmpp" ) func TestUnmarshalIqs(t *testing.T) { //var cs1 = new(iot.ControlSet) var tests = []struct { iqString string - parsedIQ IQ + parsedIQ xmpp.IQ }{ - {"", IQ{XMLName: xml.Name{Space: "", Local: "iq"}, PacketAttrs: PacketAttrs{To: "test@localhost", Type: "set", Id: "1"}}}, + {"", + xmpp.IQ{XMLName: xml.Name{Space: "", Local: "iq"}, PacketAttrs: xmpp.PacketAttrs{To: "test@localhost", Type: "set", Id: "1"}}}, //{"", IQ{XMLName: xml.Name{Space: "jabber:client", Local: "iq"}, PacketAttrs: PacketAttrs{To: "test@localhost", From: "server", Type: "set", Id: "2"}, Payload: cs1}}, } for _, test := range tests { - parsedIQ := IQ{} + parsedIQ := xmpp.IQ{} err := xml.Unmarshal([]byte(test.iqString), &parsedIQ) if err != nil { t.Errorf("Unmarshal(%s) returned error", test.iqString) @@ -33,14 +35,14 @@ func TestUnmarshalIqs(t *testing.T) { } func TestGenerateIq(t *testing.T) { - iq := NewIQ("result", "admin@localhost", "test@localhost", "1", "en") - payload := DiscoInfo{ - Identity: Identity{ + iq := xmpp.NewIQ("result", "admin@localhost", "test@localhost", "1", "en") + payload := xmpp.DiscoInfo{ + Identity: xmpp.Identity{ Name: "Test Gateway", Category: "gateway", Type: "mqtt", }, - Features: []Feature{ + Features: []xmpp.Feature{ {Var: "http://jabber.org/protocol/disco#info"}, {Var: "http://jabber.org/protocol/disco#item"}, }, @@ -56,7 +58,7 @@ func TestGenerateIq(t *testing.T) { t.Error("empty error should not be serialized") } - parsedIQ := IQ{} + parsedIQ := xmpp.IQ{} if err = xml.Unmarshal(data, &parsedIQ); err != nil { t.Errorf("Unmarshal(%s) returned error", data) } @@ -67,7 +69,7 @@ func TestGenerateIq(t *testing.T) { } func TestErrorTag(t *testing.T) { - xError := Err{ + xError := xmpp.Err{ XMLName: xml.Name{Local: "error"}, Code: 503, Type: "cancel", @@ -80,7 +82,7 @@ func TestErrorTag(t *testing.T) { t.Errorf("cannot marshal xml structure: %s", err) } - parsedError := Err{} + parsedError := xmpp.Err{} if err = xml.Unmarshal(data, &parsedError); err != nil { t.Errorf("Unmarshal(%s) returned error", data) } @@ -91,8 +93,8 @@ func TestErrorTag(t *testing.T) { } func TestDiscoItems(t *testing.T) { - iq := NewIQ("get", "romeo@montague.net/orchard", "catalog.shakespeare.lit", "items3", "en") - payload := DiscoItems{ + iq := xmpp.NewIQ("get", "romeo@montague.net/orchard", "catalog.shakespeare.lit", "items3", "en") + payload := xmpp.DiscoItems{ Node: "music", } iq.AddPayload(&payload) @@ -102,7 +104,7 @@ func TestDiscoItems(t *testing.T) { t.Errorf("cannot marshal xml structure") } - parsedIQ := IQ{} + parsedIQ := xmpp.IQ{} if err = xml.Unmarshal(data, &parsedIQ); err != nil { t.Errorf("Unmarshal(%s) returned error", data) } @@ -111,25 +113,3 @@ func TestDiscoItems(t *testing.T) { t.Errorf("non matching items\n%s", cmp.Diff(parsedIQ.Payload, iq.Payload)) } } - -// Compare iq structure but ignore empty namespace as they are set properly on -// marshal / unmarshal. There is no need to manage them on the manually -// crafted structure. -func xmlEqual(x, y interface{}) bool { - alwaysEqual := cmp.Comparer(func(_, _ interface{}) bool { return true }) - opts := cmp.Options{ - cmp.FilterValues(func(x, y interface{}) bool { - xx, xok := x.(xml.Name) - yy, yok := y.(xml.Name) - if xok && yok { - zero := xml.Name{} - if xx == zero || yy == zero { - return true - } - } - return false - }, alwaysEqual), - } - - return cmp.Equal(x, y, opts) -} diff --git a/message_test.go b/message_test.go index 888205c..21ee882 100644 --- a/message_test.go +++ b/message_test.go @@ -1,14 +1,15 @@ -package xmpp // import "gosrc.io/xmpp" +package xmpp_test import ( "encoding/xml" "testing" "github.com/google/go-cmp/cmp" + "gosrc.io/xmpp" ) func TestGenerateMessage(t *testing.T) { - message := NewMessage("chat", "admin@localhost", "test@localhost", "1", "en") + message := xmpp.NewMessage("chat", "admin@localhost", "test@localhost", "1", "en") message.Body = "Hi" message.Subject = "Msg Subject" @@ -17,7 +18,7 @@ func TestGenerateMessage(t *testing.T) { t.Errorf("cannot marshal xml structure") } - parsedMessage := Message{} + parsedMessage := xmpp.Message{} if err = xml.Unmarshal(data, &parsedMessage); err != nil { t.Errorf("Unmarshal(%s) returned error", data) } diff --git a/presence_test.go b/presence_test.go index 388ab6a..f9d9f54 100644 --- a/presence_test.go +++ b/presence_test.go @@ -1,14 +1,16 @@ -package xmpp // import "gosrc.io/xmpp" +package xmpp_test import ( "encoding/xml" "testing" + "gosrc.io/xmpp" + "github.com/google/go-cmp/cmp" ) func TestGeneratePresence(t *testing.T) { - presence := NewPresence("admin@localhost", "test@localhost", "1", "en") + presence := xmpp.NewPresence("admin@localhost", "test@localhost", "1", "en") presence.Show = "chat" data, err := xml.Marshal(presence) @@ -16,7 +18,7 @@ func TestGeneratePresence(t *testing.T) { t.Errorf("cannot marshal xml structure") } - parsedPresence := Presence{} + var parsedPresence xmpp.Presence if err = xml.Unmarshal(data, &parsedPresence); err != nil { t.Errorf("Unmarshal(%s) returned error", data) } @@ -25,3 +27,38 @@ func TestGeneratePresence(t *testing.T) { t.Errorf("non matching items\n%s", cmp.Diff(parsedPresence, presence)) } } + +func TestPresenceSubElt(t *testing.T) { + // Test structure to ensure that show, status and priority are correctly defined as presence + // package sub-elements + type pres struct { + Show string `xml:"show"` + Status string `xml:"status"` + Priority string `xml:"priority"` + } + + presence := xmpp.NewPresence("admin@localhost", "test@localhost", "1", "en") + presence.Show = "xa" + presence.Status = "Coding" + presence.Priority = "10" + + data, err := xml.Marshal(presence) + if err != nil { + t.Errorf("cannot marshal xml structure") + } + + var parsedPresence pres + if err = xml.Unmarshal(data, &parsedPresence); err != nil { + t.Errorf("Unmarshal(%s) returned error", data) + } + + if parsedPresence.Show != presence.Show { + t.Errorf("cannot read 'show' as presence subelement (%s)", parsedPresence.Show) + } + if parsedPresence.Status != presence.Status { + t.Errorf("cannot read 'status' as presence subelement (%s)", parsedPresence.Status) + } + if parsedPresence.Priority != presence.Priority { + t.Errorf("cannot read 'priority' as presence subelement (%s)", parsedPresence.Priority) + } +} diff --git a/test.sh b/test.sh index 341553c..9730026 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +export GO111MODULE=on echo "" > coverage.txt for d in $(go list ./... | grep -v vendor); do diff --git a/xmpp_test.go b/xmpp_test.go new file mode 100644 index 0000000..7f7e6de --- /dev/null +++ b/xmpp_test.go @@ -0,0 +1,29 @@ +package xmpp_test + +import ( + "encoding/xml" + + "github.com/google/go-cmp/cmp" +) + +// Compare iq structure but ignore empty namespace as they are set properly on +// marshal / unmarshal. There is no need to manage them on the manually +// crafted structure. +func xmlEqual(x, y interface{}) bool { + alwaysEqual := cmp.Comparer(func(_, _ interface{}) bool { return true }) + opts := cmp.Options{ + cmp.FilterValues(func(x, y interface{}) bool { + xx, xok := x.(xml.Name) + yy, yok := y.(xml.Name) + if xok && yok { + zero := xml.Name{} + if xx == zero || yy == zero { + return true + } + } + return false + }, alwaysEqual), + } + + return cmp.Equal(x, y, opts) +}