Merge branch 'feature/reach-updater-client' into develop
This commit is contained in:
commit
52bac70174
8
Makefile
8
Makefile
|
@ -13,7 +13,7 @@ test: tidy
|
||||||
go test -mod=vendor -v ./...
|
go test -mod=vendor -v ./...
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@PATH=$(PATH):./bin/gometalinter gometalinter -e '.*/pkg/mod' -e ".*/go/src" --vendor ./...
|
@PATH=$(PATH):./bin/gometalinter gometalinter -e '.*/pkg/mod' -e ".*/go/src" --vendor $(LINT_ARGS) ./...
|
||||||
|
|
||||||
tidy:
|
tidy:
|
||||||
go mod tidy
|
go mod tidy
|
||||||
|
@ -31,4 +31,8 @@ clean:
|
||||||
rm -rf ./bin
|
rm -rf ./bin
|
||||||
go clean -i -x -r -modcache
|
go clean -i -x -r -modcache
|
||||||
|
|
||||||
.PHONY: test clean generate vendor install-devtools lint watch tidy
|
doc:
|
||||||
|
@echo "Open your browser to http://localhost:6060/pkg/forge.cadoles.com/Pyxis/orion/ to see the documentation"
|
||||||
|
@godoc -http=:6060
|
||||||
|
|
||||||
|
.PHONY: test clean generate vendor install-devtools lint watch tidy doc
|
2
go.mod
2
go.mod
|
@ -1,7 +1,7 @@
|
||||||
module forge.cadoles.com/Pyxis/orion
|
module forge.cadoles.com/Pyxis/orion
|
||||||
|
|
||||||
require (
|
require (
|
||||||
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919081902-52a9157a070d
|
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919100209-bb857ced6b95
|
||||||
github.com/caarlos0/env v3.3.0+incompatible
|
github.com/caarlos0/env v3.3.0+incompatible
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/go-chi/chi v3.3.3+incompatible
|
github.com/go-chi/chi v3.3.3+incompatible
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,5 @@
|
||||||
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919081902-52a9157a070d h1:gkJw6IeJ+A/EVw48eUnZwbK36fBlDrfB5lNyEPAltLQ=
|
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919100209-bb857ced6b95 h1:o3G5+9RjczCK1xAYFaRMknk1kY9Ule6PNfiW6N6hEpg=
|
||||||
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919081902-52a9157a070d/go.mod h1:I6kYOFWNkFlNeQLI7ZqfTRz4NdPHZxX0Bzizmzgchs0=
|
forge.cadoles.com/Pyxis/golang-socketio v0.0.0-20180919100209-bb857ced6b95/go.mod h1:I6kYOFWNkFlNeQLI7ZqfTRz4NdPHZxX0Bzizmzgchs0=
|
||||||
github.com/caarlos0/env v3.3.0+incompatible h1:jCfY0ilpzC2FFViyZyDKCxKybDESTwaR+ebh8zm6AOE=
|
github.com/caarlos0/env v3.3.0+incompatible h1:jCfY0ilpzC2FFViyZyDKCxKybDESTwaR+ebh8zm6AOE=
|
||||||
github.com/caarlos0/env v3.3.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
|
github.com/caarlos0/env v3.3.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
|
|
@ -11,6 +11,7 @@ Makefile {
|
||||||
**/*.go
|
**/*.go
|
||||||
modd.conf
|
modd.conf
|
||||||
Makefile {
|
Makefile {
|
||||||
|
prep: make lint LINT_ARGS=--fast
|
||||||
prep: make test
|
prep: make test
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,20 @@ import (
|
||||||
const (
|
const (
|
||||||
// EventBrowserConnected is emitted after the initial connection to the
|
// EventBrowserConnected is emitted after the initial connection to the
|
||||||
// ReachView endpoint
|
// ReachView endpoint
|
||||||
EventBrowserConnected = "browser connected"
|
eventBrowserConnected = "browser connected"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sendBrowserConnected notifies the ReachView endpoint
|
// sendBrowserConnected notifies the ReachView endpoint
|
||||||
// of a new connection.
|
// of a new connection.
|
||||||
// See misc/reachview/update_main.js line 297
|
// See misc/reachview/update_main.js line 297
|
||||||
func (c *Client) sendBrowserConnected() error {
|
func (c *client) sendBrowserConnected() error {
|
||||||
payload := map[string]string{
|
payload := map[string]string{
|
||||||
"data": "I'm connected",
|
"data": "I'm connected",
|
||||||
}
|
}
|
||||||
c.logf("sending '%s' event", EventBrowserConnected)
|
c.logf("sending '%s' event", eventBrowserConnected)
|
||||||
if err := c.conn.Emit(EventBrowserConnected, payload); err != nil {
|
if err := c.conn.Emit(eventBrowserConnected, payload); err != nil {
|
||||||
return errors.Wrapf(err, "error while emitting '%s' event", EventBrowserConnected)
|
return errors.Wrapf(err, "error while emitting '%s' event", eventBrowserConnected)
|
||||||
}
|
}
|
||||||
c.logf("'%s' event sent", EventBrowserConnected)
|
c.logf("'%s' event sent", eventBrowserConnected)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,26 +2,20 @@ package reach
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"forge.cadoles.com/Pyxis/golang-socketio"
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
"forge.cadoles.com/Pyxis/golang-socketio/transport"
|
"forge.cadoles.com/Pyxis/golang-socketio/transport"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type handshake struct {
|
type client struct {
|
||||||
PingInterval time.Duration `json:"pingInterval"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client is a ReachView Websocket API client
|
|
||||||
type Client struct {
|
|
||||||
opts *Options
|
opts *Options
|
||||||
conn *gosocketio.Client
|
conn *gosocketio.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect connects the client to the ReachView endpoint
|
// Connect connects the client to the ReachView endpoint
|
||||||
// This method is not safe to call by different coroutines
|
// This method is not safe to call by different coroutines
|
||||||
func (c *Client) Connect() error {
|
func (c *client) Connect() error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -71,7 +65,7 @@ func (c *Client) Connect() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the current connection to the ReachView endpoint
|
// Close closes the current connection to the ReachView endpoint
|
||||||
func (c *Client) Close() {
|
func (c *client) Close() {
|
||||||
if c.conn == nil {
|
if c.conn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -80,20 +74,19 @@ func (c *Client) Close() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) logf(format string, args ...interface{}) {
|
func (c *client) logf(format string, args ...interface{}) {
|
||||||
if c.opts.Logger == nil {
|
if c.opts.Logger == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.opts.Logger.Printf(format, args...)
|
c.opts.Logger.Printf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a new ReachView Websocket API client
|
func newClient(opts ...OptionFunc) *client {
|
||||||
func NewClient(opts ...OptionFunc) *Client {
|
|
||||||
options := DefaultOptions()
|
options := DefaultOptions()
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(options)
|
o(options)
|
||||||
}
|
}
|
||||||
return &Client{
|
return &client{
|
||||||
opts: options,
|
opts: options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
// ReachRS modules provides an Updater application when reset in factory mode.
|
||||||
|
// This package provides an API to communicate with this application.
|
||||||
|
func Example_updaterClientUsage() {
|
||||||
|
// Create a new Updater client instance
|
||||||
|
updater := NewUpdaterClient(
|
||||||
|
WithEndpoint("192.168.42.1", 80), // Define the module endpoint
|
||||||
|
)
|
||||||
|
|
||||||
|
// Connect to the ReachRS Updater endpoint
|
||||||
|
if err := updater.Connect(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
networks, err := updater.SavedWifiNetworks()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do something with network
|
||||||
|
for _, n := range networks {
|
||||||
|
log.Printf("Save WiFi network: SSID: '%s', Security: '%s'", n.SSID, n.Security)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dont forget to close the connection when you are done
|
||||||
|
defer updater.Close()
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
package reach
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"forge.cadoles.com/Pyxis/golang-socketio"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EventProbe -
|
|
||||||
EventProbe = "probe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Probe -
|
|
||||||
func (c *Client) Probe() error {
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
c.conn.On(EventProbe, func(h *gosocketio.Channel) {
|
|
||||||
wg.Done()
|
|
||||||
c.conn.On(EventProbe, nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.logf("sending '%s' event", EventProbe)
|
|
||||||
if err := c.conn.Emit(EventProbe, nil); err != nil {
|
|
||||||
return errors.Wrapf(err, "error while emitting '%s' event", EventProbe)
|
|
||||||
}
|
|
||||||
c.logf("'%s' event sent", EventProbe)
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Package reach is a package to configure EMLID ReachRS modules in Go.
|
||||||
|
//
|
||||||
|
// It aims to provide a simple interface to common ReachRS modules management operations.
|
||||||
|
package reach
|
|
@ -0,0 +1,49 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventGetReachViewVersion = "get reachview version"
|
||||||
|
eventReachViewVersionResults = "current reachview version"
|
||||||
|
)
|
||||||
|
|
||||||
|
type reachViewVersion struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReachViewVersion returns the ReachRS module ReachView version
|
||||||
|
func (u *Updater) ReachViewVersion() (string, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var version string
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventReachViewVersionResults, func(h *gosocketio.Channel, rv *reachViewVersion) {
|
||||||
|
version = rv.Version
|
||||||
|
u.conn.Off(eventReachViewVersionResults)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "error while binding to '%s' event", eventReachViewVersionResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventGetReachViewVersion)
|
||||||
|
if err = u.conn.Emit(eventGetReachViewVersion, nil); err != nil {
|
||||||
|
return "", errors.Wrapf(err, "error while emitting '%s' event", eventGetReachViewVersion)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventGetReachViewVersion)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
u.logf("reachview version result: %v", version)
|
||||||
|
|
||||||
|
return version, err
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientReachViewVersion(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
version, err := client.ReachViewVersion()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if version == "" {
|
||||||
|
t.Error("version should not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventReboot = "reboot now"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RebootNow asks the ReachRS module to reboot now
|
||||||
|
func (u *Updater) RebootNow() error {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventReboot)
|
||||||
|
if err = u.conn.Emit(eventReboot, nil); err != nil {
|
||||||
|
return errors.Wrapf(err, "error while emitting '%s' event", eventReboot)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventReboot)
|
||||||
|
|
||||||
|
return err
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientReboutNow(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := client.RebootNow(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventIsReceiverUpgradeAvailable = "is receiver upgrade available"
|
||||||
|
eventReceiverUpgradeAvailable = "receiver upgrade available"
|
||||||
|
)
|
||||||
|
|
||||||
|
type receiverUpgreAvailable struct {
|
||||||
|
Available bool `json:"available"`
|
||||||
|
Running bool `json:"running"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiverUpgradeAvailable checks if an upgrade is avaialable/running for the ReachRS module
|
||||||
|
func (u *Updater) ReceiverUpgradeAvailable() (available bool, running bool, err error) {
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventReceiverUpgradeAvailable, func(h *gosocketio.Channel, up *receiverUpgreAvailable) {
|
||||||
|
available = up.Available
|
||||||
|
running = up.Running
|
||||||
|
u.conn.Off(eventReceiverUpgradeAvailable)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, false, errors.Wrapf(err, "error while binding to '%s' event", eventReceiverUpgradeAvailable)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventIsReceiverUpgradeAvailable)
|
||||||
|
if err = u.conn.Emit(eventIsReceiverUpgradeAvailable, nil); err != nil {
|
||||||
|
return false, false, errors.Wrapf(err, "error while emitting '%s' event", eventIsReceiverUpgradeAvailable)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventIsReceiverUpgradeAvailable)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
u.logf("receiver upgrade result: available: %v, running: %v", available, running)
|
||||||
|
|
||||||
|
return available, running, err
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientReceiverUpgradeAvailable(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := client.ReceiverUpgradeAvailable()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import "flag"
|
||||||
|
|
||||||
|
var runUpdaterIntegrationTests = flag.Bool(
|
||||||
|
"updater-integration", false,
|
||||||
|
"Run the 'Updater' integration tests (in addition to the unit tests)",
|
||||||
|
)
|
||||||
|
|
||||||
|
var reachHost = flag.String(
|
||||||
|
"reach-host", "192.168.42.1",
|
||||||
|
"The Reach module host to use in integration tests",
|
||||||
|
)
|
|
@ -8,10 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// EventGetTestResults is a request for the ReachRS module's test results
|
eventGetTestResults = "get test results"
|
||||||
EventGetTestResults = "get test results"
|
eventTestResults = "test results"
|
||||||
// EventTestResults is the response of the EventGetTestResults request
|
|
||||||
EventTestResults = "test results"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestResults are the ReachRS module's test results
|
// TestResults are the ReachRS module's test results
|
||||||
|
@ -24,7 +22,7 @@ type TestResults struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestResults returns the ReachRS module tests results
|
// TestResults returns the ReachRS module tests results
|
||||||
func (c *Client) TestResults() (*TestResults, error) {
|
func (u *Updater) TestResults() (*TestResults, error) {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var results *TestResults
|
var results *TestResults
|
||||||
|
@ -32,17 +30,20 @@ func (c *Client) TestResults() (*TestResults, error) {
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
c.conn.On(EventTestResults, func(h *gosocketio.Channel, res *TestResults) {
|
err = u.conn.On(eventTestResults, func(h *gosocketio.Channel, res *TestResults) {
|
||||||
results = res
|
results = res
|
||||||
c.conn.On(EventTestResults, nil)
|
u.conn.Off(eventTestResults)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
c.logf("sending '%s' event", EventGetTestResults)
|
return nil, errors.Wrapf(err, "error while binding to '%s' event", eventTestResults)
|
||||||
if err = c.conn.Emit(EventGetTestResults, nil); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error while emitting '%s' event", EventGetTestResults)
|
|
||||||
}
|
}
|
||||||
c.logf("'%s' event sent", EventGetTestResults)
|
|
||||||
|
u.logf("sending '%s' event", eventGetTestResults)
|
||||||
|
if err = u.conn.Emit(eventGetTestResults, nil); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error while emitting '%s' event", eventGetTestResults)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventGetTestResults)
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,15 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClient(t *testing.T) {
|
func TestClientTestResults(t *testing.T) {
|
||||||
|
|
||||||
client := NewClient(
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
WithStandardLogger(),
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
)
|
)
|
||||||
if err := client.Connect(); err != nil {
|
if err := client.Connect(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
|
@ -0,0 +1,49 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventGetTimeSyncStatus = "get time sync status"
|
||||||
|
eventTimeSyncResults = "time sync status"
|
||||||
|
)
|
||||||
|
|
||||||
|
type timeSyncStatus struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimeSyncStatus returns the ReachRS module time sync status
|
||||||
|
func (u *Updater) TimeSyncStatus() (bool, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var synced bool
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventTimeSyncResults, func(h *gosocketio.Channel, st *timeSyncStatus) {
|
||||||
|
synced = st.Status
|
||||||
|
u.conn.Off(eventTimeSyncResults)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while binding to '%s' event", eventTimeSyncResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventGetTimeSyncStatus)
|
||||||
|
if err = u.conn.Emit(eventGetTimeSyncStatus, nil); err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while emitting '%s' event", eventGetTimeSyncStatus)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventGetTimeSyncStatus)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
u.logf("time sync result: %v", synced)
|
||||||
|
|
||||||
|
return synced, err
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientTimeSync(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := client.TimeSyncStatus()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventUpdate = "update"
|
||||||
|
eventOPKGUpdateResult = "opkg update result"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateStatus embeds informations about update status
|
||||||
|
type UpdateStatus struct {
|
||||||
|
Active bool `json:"active"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Locked bool `json:"locked"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update asks the ReachRS module to start an OPKG update
|
||||||
|
func (u *Updater) Update() (*UpdateStatus, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var status *UpdateStatus
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventOPKGUpdateResult, func(h *gosocketio.Channel, st *UpdateStatus) {
|
||||||
|
status = st
|
||||||
|
u.conn.Off(eventOPKGUpdateResult)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error while binding to '%s' event", eventOPKGUpdateResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventUpdate)
|
||||||
|
if err = u.conn.Emit(eventUpdate, nil); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error while emitting '%s' event", eventUpdate)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventUpdate)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
u.logf(
|
||||||
|
"opkg update result: active: %v, state: %v, locked: %v",
|
||||||
|
status.Active, status.State, status.Locked,
|
||||||
|
)
|
||||||
|
|
||||||
|
return status, err
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientOPKGUpdate(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := client.Update()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
// Updater is a ReachRS Updater client
|
||||||
|
type Updater struct {
|
||||||
|
*client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUpdaterClient returns a new ReachRS Updater client
|
||||||
|
func NewUpdaterClient(opts ...OptionFunc) *Updater {
|
||||||
|
client := newClient(opts...)
|
||||||
|
return &Updater{client}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"forge.cadoles.com/Pyxis/golang-socketio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eventGetSavedWifiNetworks = "get saved wifi networks"
|
||||||
|
eventSavedWifiNetworkResults = "wifi saved networks results"
|
||||||
|
eventAddWifiNetwork = "add new network"
|
||||||
|
eventAddWifiNetworkResults = "add network results"
|
||||||
|
eventRemoveWifiNetwork = "remove network"
|
||||||
|
eventRemoveWifiNetworkResults = "remove network results"
|
||||||
|
eventConnectToNetwork = "connect to network"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WifiSecurity is a WiFi network security algorithm
|
||||||
|
type WifiSecurity string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SecurityWEP WEP wifi network
|
||||||
|
SecurityWEP WifiSecurity = "wep"
|
||||||
|
// SecurityWPAPSK WPA(2)-PSK wifi network
|
||||||
|
SecurityWPAPSK WifiSecurity = "wpa-psk"
|
||||||
|
// SecurityOpen Open wifi network
|
||||||
|
SecurityOpen WifiSecurity = "open"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WifiNetwork is a ReachRS module's saved wifi network
|
||||||
|
// Raw messages examples:
|
||||||
|
type WifiNetwork struct {
|
||||||
|
SSID string `json:"ssid"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Security WifiSecurity `json:"security"`
|
||||||
|
Identity string `json:"identity"`
|
||||||
|
Visible bool `json:"is_visible"`
|
||||||
|
Connected bool `json:"is_connected"`
|
||||||
|
Added bool `json:"is_added"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SavedWifiNetworks returns the ReachRS module saved wifi networks
|
||||||
|
func (u *Updater) SavedWifiNetworks() ([]*WifiNetwork, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var wifiNetworks []*WifiNetwork
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventSavedWifiNetworkResults, func(h *gosocketio.Channel, wn []*WifiNetwork) {
|
||||||
|
wifiNetworks = wn
|
||||||
|
u.conn.Off(eventSavedWifiNetworkResults)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error while binding to '%s' event", eventSavedWifiNetworkResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventGetSavedWifiNetworks)
|
||||||
|
if err = u.conn.Emit(eventGetSavedWifiNetworks, nil); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error while emitting '%s' event", eventGetSavedWifiNetworks)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventGetSavedWifiNetworks)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return wifiNetworks, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddWifiNetwork asks the ReachRS module to save the given wifi network informations
|
||||||
|
func (u *Updater) AddWifiNetwork(ssid string, security WifiSecurity, password string) (bool, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var done bool
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventAddWifiNetworkResults, func(h *gosocketio.Channel, d bool) {
|
||||||
|
done = d
|
||||||
|
u.conn.Off(eventAddWifiNetworkResults)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while binding to '%s' event", eventAddWifiNetworkResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
wn := &WifiNetwork{
|
||||||
|
SSID: ssid,
|
||||||
|
Security: security,
|
||||||
|
Password: password,
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventAddWifiNetwork)
|
||||||
|
if err = u.conn.Emit(eventAddWifiNetwork, wn); err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while emitting '%s' event", eventAddWifiNetwork)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventAddWifiNetwork)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return done, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveWifiNetwork asks the ReachRS module to remove the given WiFi network
|
||||||
|
func (u *Updater) RemoveWifiNetwork(ssid string) (bool, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var done bool
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
|
err = u.conn.On(eventRemoveWifiNetworkResults, func(h *gosocketio.Channel, d bool) {
|
||||||
|
done = d
|
||||||
|
u.conn.Off(eventRemoveWifiNetworkResults)
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while binding to '%s' event", eventRemoveWifiNetworkResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.logf("sending '%s' event", eventRemoveWifiNetwork)
|
||||||
|
if err := u.conn.Emit(eventRemoveWifiNetwork, ssid); err != nil {
|
||||||
|
return false, errors.Wrapf(err, "error while emitting '%s' event", eventRemoveWifiNetwork)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventRemoveWifiNetwork)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return done, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectToWifiNetwork asks the ReachRS module to connect to the given WiFi network
|
||||||
|
func (u *Updater) ConnectToWifiNetwork(ssid string) error {
|
||||||
|
u.logf("sending '%s' event", eventConnectToNetwork)
|
||||||
|
if err := u.conn.Emit(eventConnectToNetwork, ssid); err != nil {
|
||||||
|
return errors.Wrapf(err, "error while emitting '%s' event", eventConnectToNetwork)
|
||||||
|
}
|
||||||
|
u.logf("'%s' event sent", eventConnectToNetwork)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package reach
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientSavedWiFiNetworks(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := client.SavedWifiNetworks()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientCRUDWiFiNetwork(t *testing.T) {
|
||||||
|
|
||||||
|
if !*runUpdaterIntegrationTests {
|
||||||
|
t.Skip("To run this test, use: go test -updater-integration")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := NewUpdaterClient(
|
||||||
|
WithStandardLogger(),
|
||||||
|
WithEndpoint(*reachHost, 80),
|
||||||
|
)
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid := fmt.Sprintf("wifi_test_%d", rand.Uint32())
|
||||||
|
|
||||||
|
done, err := client.AddWifiNetwork(ssid, SecurityOpen, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := done, true; g != e {
|
||||||
|
t.Errorf("AddWifiNetwork() -> done: got '%v', expected '%v'", g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
networks, err := client.SavedWifiNetworks()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, n := range networks {
|
||||||
|
if n.SSID == ssid {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := found, true; g != e {
|
||||||
|
t.Errorf("wifi network '%s' should exists", ssid)
|
||||||
|
}
|
||||||
|
|
||||||
|
done, err = client.RemoveWifiNetwork(ssid)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := done, true; g != e {
|
||||||
|
t.Errorf("RemoveWifiNetwork() -> done: got '%v', expected '%v'", g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
}
|
Reference in New Issue