Merge branch 'master' into xmpp-check
This commit is contained in:
commit
c55257cbed
|
@ -1,5 +1,5 @@
|
||||||
FROM golang:1.11
|
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
|
RUN curl -o codecov.sh -s https://codecov.io/bash && chmod +x codecov.sh
|
||||||
COPY . ./
|
COPY . ./
|
||||||
RUN go get -t ./...
|
# RUN go get -t ./...
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package xmpp
|
package xmpp // import "gosrc.io/xmpp"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
|
@ -119,7 +119,7 @@ func (c *Client) Connect() (*Session, error) {
|
||||||
var try = 0
|
var try = 0
|
||||||
var success bool
|
var success bool
|
||||||
c.Metrics = initMetrics()
|
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 {
|
if tcpconn, err = net.DialTimeout("tcp", c.config.Address, time.Duration(c.config.ConnectTimeout)*time.Second); err == nil {
|
||||||
c.Metrics.setConnectTime()
|
c.Metrics.setConnectTime()
|
||||||
success = true
|
success = true
|
||||||
|
|
28
cmd/xmpp-check/README.md
Normal file
28
cmd/xmpp-check/README.md
Normal file
|
@ -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.
|
52
iq_test.go
52
iq_test.go
|
@ -1,4 +1,4 @@
|
||||||
package xmpp // import "gosrc.io/xmpp"
|
package xmpp_test // import "gosrc.io/xmpp"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
@ -6,20 +6,22 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"gosrc.io/xmpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnmarshalIqs(t *testing.T) {
|
func TestUnmarshalIqs(t *testing.T) {
|
||||||
//var cs1 = new(iot.ControlSet)
|
//var cs1 = new(iot.ControlSet)
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
iqString string
|
iqString string
|
||||||
parsedIQ IQ
|
parsedIQ xmpp.IQ
|
||||||
}{
|
}{
|
||||||
{"<iq id=\"1\" type=\"set\" to=\"test@localhost\"/>", IQ{XMLName: xml.Name{Space: "", Local: "iq"}, PacketAttrs: PacketAttrs{To: "test@localhost", Type: "set", Id: "1"}}},
|
{"<iq id=\"1\" type=\"set\" to=\"test@localhost\"/>",
|
||||||
|
xmpp.IQ{XMLName: xml.Name{Space: "", Local: "iq"}, PacketAttrs: xmpp.PacketAttrs{To: "test@localhost", Type: "set", Id: "1"}}},
|
||||||
//{"<iq xmlns=\"jabber:client\" id=\"2\" type=\"set\" to=\"test@localhost\" from=\"server\"><set xmlns=\"urn:xmpp:iot:control\"/></iq>", IQ{XMLName: xml.Name{Space: "jabber:client", Local: "iq"}, PacketAttrs: PacketAttrs{To: "test@localhost", From: "server", Type: "set", Id: "2"}, Payload: cs1}},
|
//{"<iq xmlns=\"jabber:client\" id=\"2\" type=\"set\" to=\"test@localhost\" from=\"server\"><set xmlns=\"urn:xmpp:iot:control\"/></iq>", 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 {
|
for _, test := range tests {
|
||||||
parsedIQ := IQ{}
|
parsedIQ := xmpp.IQ{}
|
||||||
err := xml.Unmarshal([]byte(test.iqString), &parsedIQ)
|
err := xml.Unmarshal([]byte(test.iqString), &parsedIQ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", test.iqString)
|
t.Errorf("Unmarshal(%s) returned error", test.iqString)
|
||||||
|
@ -33,14 +35,14 @@ func TestUnmarshalIqs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateIq(t *testing.T) {
|
func TestGenerateIq(t *testing.T) {
|
||||||
iq := NewIQ("result", "admin@localhost", "test@localhost", "1", "en")
|
iq := xmpp.NewIQ("result", "admin@localhost", "test@localhost", "1", "en")
|
||||||
payload := DiscoInfo{
|
payload := xmpp.DiscoInfo{
|
||||||
Identity: Identity{
|
Identity: xmpp.Identity{
|
||||||
Name: "Test Gateway",
|
Name: "Test Gateway",
|
||||||
Category: "gateway",
|
Category: "gateway",
|
||||||
Type: "mqtt",
|
Type: "mqtt",
|
||||||
},
|
},
|
||||||
Features: []Feature{
|
Features: []xmpp.Feature{
|
||||||
{Var: "http://jabber.org/protocol/disco#info"},
|
{Var: "http://jabber.org/protocol/disco#info"},
|
||||||
{Var: "http://jabber.org/protocol/disco#item"},
|
{Var: "http://jabber.org/protocol/disco#item"},
|
||||||
},
|
},
|
||||||
|
@ -56,7 +58,7 @@ func TestGenerateIq(t *testing.T) {
|
||||||
t.Error("empty error should not be serialized")
|
t.Error("empty error should not be serialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedIQ := IQ{}
|
parsedIQ := xmpp.IQ{}
|
||||||
if err = xml.Unmarshal(data, &parsedIQ); err != nil {
|
if err = xml.Unmarshal(data, &parsedIQ); err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", data)
|
t.Errorf("Unmarshal(%s) returned error", data)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +69,7 @@ func TestGenerateIq(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorTag(t *testing.T) {
|
func TestErrorTag(t *testing.T) {
|
||||||
xError := Err{
|
xError := xmpp.Err{
|
||||||
XMLName: xml.Name{Local: "error"},
|
XMLName: xml.Name{Local: "error"},
|
||||||
Code: 503,
|
Code: 503,
|
||||||
Type: "cancel",
|
Type: "cancel",
|
||||||
|
@ -80,7 +82,7 @@ func TestErrorTag(t *testing.T) {
|
||||||
t.Errorf("cannot marshal xml structure: %s", err)
|
t.Errorf("cannot marshal xml structure: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedError := Err{}
|
parsedError := xmpp.Err{}
|
||||||
if err = xml.Unmarshal(data, &parsedError); err != nil {
|
if err = xml.Unmarshal(data, &parsedError); err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", data)
|
t.Errorf("Unmarshal(%s) returned error", data)
|
||||||
}
|
}
|
||||||
|
@ -91,8 +93,8 @@ func TestErrorTag(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDiscoItems(t *testing.T) {
|
func TestDiscoItems(t *testing.T) {
|
||||||
iq := NewIQ("get", "romeo@montague.net/orchard", "catalog.shakespeare.lit", "items3", "en")
|
iq := xmpp.NewIQ("get", "romeo@montague.net/orchard", "catalog.shakespeare.lit", "items3", "en")
|
||||||
payload := DiscoItems{
|
payload := xmpp.DiscoItems{
|
||||||
Node: "music",
|
Node: "music",
|
||||||
}
|
}
|
||||||
iq.AddPayload(&payload)
|
iq.AddPayload(&payload)
|
||||||
|
@ -102,7 +104,7 @@ func TestDiscoItems(t *testing.T) {
|
||||||
t.Errorf("cannot marshal xml structure")
|
t.Errorf("cannot marshal xml structure")
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedIQ := IQ{}
|
parsedIQ := xmpp.IQ{}
|
||||||
if err = xml.Unmarshal(data, &parsedIQ); err != nil {
|
if err = xml.Unmarshal(data, &parsedIQ); err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", data)
|
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))
|
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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package xmpp // import "gosrc.io/xmpp"
|
package xmpp_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"gosrc.io/xmpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGenerateMessage(t *testing.T) {
|
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.Body = "Hi"
|
||||||
message.Subject = "Msg Subject"
|
message.Subject = "Msg Subject"
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ func TestGenerateMessage(t *testing.T) {
|
||||||
t.Errorf("cannot marshal xml structure")
|
t.Errorf("cannot marshal xml structure")
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedMessage := Message{}
|
parsedMessage := xmpp.Message{}
|
||||||
if err = xml.Unmarshal(data, &parsedMessage); err != nil {
|
if err = xml.Unmarshal(data, &parsedMessage); err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", data)
|
t.Errorf("Unmarshal(%s) returned error", data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package xmpp // import "gosrc.io/xmpp"
|
package xmpp_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gosrc.io/xmpp"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGeneratePresence(t *testing.T) {
|
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"
|
presence.Show = "chat"
|
||||||
|
|
||||||
data, err := xml.Marshal(presence)
|
data, err := xml.Marshal(presence)
|
||||||
|
@ -16,7 +18,7 @@ func TestGeneratePresence(t *testing.T) {
|
||||||
t.Errorf("cannot marshal xml structure")
|
t.Errorf("cannot marshal xml structure")
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedPresence := Presence{}
|
var parsedPresence xmpp.Presence
|
||||||
if err = xml.Unmarshal(data, &parsedPresence); err != nil {
|
if err = xml.Unmarshal(data, &parsedPresence); err != nil {
|
||||||
t.Errorf("Unmarshal(%s) returned error", data)
|
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))
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
test.sh
1
test.sh
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
export GO111MODULE=on
|
||||||
echo "" > coverage.txt
|
echo "" > coverage.txt
|
||||||
|
|
||||||
for d in $(go list ./... | grep -v vendor); do
|
for d in $(go list ./... | grep -v vendor); do
|
||||||
|
|
29
xmpp_test.go
Normal file
29
xmpp_test.go
Normal file
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in a new issue