2024-07-30 14:28:39 +02:00
|
|
|
package testsuite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-08-02 12:57:07 +02:00
|
|
|
"math/rand"
|
2024-07-30 14:28:39 +02:00
|
|
|
"os"
|
2024-08-02 12:57:07 +02:00
|
|
|
"strconv"
|
2024-07-30 14:28:39 +02:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"forge.cadoles.com/cadoles/go-emlid/reach"
|
|
|
|
"forge.cadoles.com/cadoles/go-emlid/reach/client/protocol"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type OperationsFactoryFunc func(addr string) (protocol.Operations, error)
|
|
|
|
|
|
|
|
type operationTestCase struct {
|
|
|
|
Name string
|
|
|
|
Run func(t *testing.T, ops protocol.Operations)
|
|
|
|
}
|
|
|
|
|
|
|
|
var testCases = []operationTestCase{
|
|
|
|
{
|
|
|
|
Name: "Connect to ReachView",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
alive, err := ops.Alive(ctx)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := true, alive; e != g {
|
|
|
|
t.Errorf("alive: expected '%v', got '%v'", e, g)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Retrieve ReachView version",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-08-02 12:57:07 +02:00
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
version, stable, err := ops.Version(ctx)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("ReachView version: %s", version)
|
|
|
|
t.Logf("ReachView stable channel: %v", stable)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Listen to ReachView 'broadcast' messages",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
broadcastCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
messages, err := ops.On(broadcastCtx, "broadcast")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
|
|
for m := range messages {
|
|
|
|
t.Logf("new message: %s", spew.Sdump(m))
|
|
|
|
count++
|
|
|
|
}
|
|
|
|
|
|
|
|
if e, g := 1, count; g < e {
|
|
|
|
t.Errorf("expected total messages > %d, got %d", e, g)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Retrieve module configuration",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-08-02 12:57:07 +02:00
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
config, err := ops.Configuration(ctx)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("Module configuration: %s", spew.Sdump(config))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Set base",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2024-08-02 12:57:07 +02:00
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
latitude := -90 + rand.Float64()*180
|
|
|
|
longitude := -180 + rand.Float64()*360
|
|
|
|
height := rand.Float64() * 1000
|
|
|
|
antennaOffset := rand.Float64() * 2
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
opts := []protocol.SetBaseOptionFunc{
|
2024-08-02 12:57:07 +02:00
|
|
|
protocol.WithBaseLatitude(latitude),
|
|
|
|
protocol.WithBaseLongitude(longitude),
|
|
|
|
protocol.WithBaseHeight(height),
|
|
|
|
protocol.WithBaseAntennaOffset(antennaOffset),
|
2024-07-30 14:28:39 +02:00
|
|
|
protocol.WithBaseMode("manual"),
|
|
|
|
}
|
|
|
|
|
2024-08-02 12:57:07 +02:00
|
|
|
t.Logf("setting base (latitude: %v, longitude: %v, height: %v, antennaOffset: %v", latitude, longitude, height, antennaOffset)
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
if err := ops.SetBase(ctx, opts...); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-09-18 15:20:41 +02:00
|
|
|
config, err := ops.Configuration(ctx)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("updated configuration: %v", spew.Sdump(config))
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Reboot",
|
|
|
|
Run: func(t *testing.T, ops protocol.Operations) {
|
2024-08-02 12:57:07 +02:00
|
|
|
const doRebootEnvVar = "DO_REBOOT"
|
|
|
|
rawDoReboot := os.Getenv(doRebootEnvVar)
|
|
|
|
if rawDoReboot == "" {
|
|
|
|
rawDoReboot = "false"
|
|
|
|
}
|
|
|
|
|
|
|
|
doReboot, err := strconv.ParseBool(rawDoReboot)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("could not parse %s environment variable: %+v", doRebootEnvVar, errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if !doReboot {
|
|
|
|
t.Skipf("Reboot test case disabled. To enable, set environment variable %s=true", doRebootEnvVar)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-30 14:28:39 +02:00
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
if err := ops.Connect(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := ops.Close(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
if err := ops.Reboot(ctx); err != nil {
|
|
|
|
t.Errorf("%+v", errors.WithStack(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestOperations(t *testing.T, opsFactory OperationsFactoryFunc) {
|
|
|
|
reach.AssertIntegrationTests(t)
|
|
|
|
|
|
|
|
addr := os.Getenv("REACHRS_HOST")
|
|
|
|
if addr == "" {
|
|
|
|
addr = "192.168.42.1"
|
|
|
|
t.Logf("Targeting '%s'. You can modify targeted host by specifying environment variable REACHRS_HOST", addr)
|
|
|
|
} else {
|
|
|
|
t.Logf("Targeting '%s'", addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
|
|
ops, err := opsFactory(addr)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("could not initialize protocol operations: %+v", errors.WithStack(err))
|
|
|
|
}
|
|
|
|
|
|
|
|
tc.Run(t, ops)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|