-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8508e1b
commit 0be1629
Showing
10 changed files
with
319 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package integrationtest | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"os/exec" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"github.com/yalp/jsonpath" | ||
) | ||
|
||
func run(ctx context.Context, t *testing.T, wDevice bool, args ...string) (out, logs string, exitCode int) { | ||
if wDevice { | ||
// echo-min-json roundtrips the response through the parser so we can also verify the parsing. | ||
args = append([]string{"--host", iTest.uri, "-o", "echo-min-json"}, args...) | ||
} | ||
t.Logf("Running: %s %s", iTest.binPath, strings.Join(args, " ")) | ||
cmd := exec.CommandContext(iTest.ctx, iTest.binPath, args...) | ||
var stdout, stderr bytes.Buffer | ||
cmd.Stdout = &stdout | ||
cmd.Stderr = &stderr | ||
if err := cmd.Run(); err != nil { | ||
var eErr *exec.ExitError | ||
if errors.As(err, &eErr) { | ||
return stdout.String(), stderr.String(), eErr.ExitCode() | ||
} | ||
t.Fatalf("cmd %s %s err: %v", iTest.binPath, strings.Join(args, " "), err) | ||
} | ||
return stdout.String(), stderr.String(), 0 | ||
} | ||
|
||
func jsonGet(t *testing.T, actual, path string) any { | ||
t.Helper() | ||
var data any | ||
err := json.Unmarshal([]byte(actual), &data) | ||
require.NoError(t, err) | ||
v, err := jsonpath.Read(data, path) | ||
require.NoError(t, err) | ||
return v | ||
} | ||
|
||
func jsonAssertEqual(t *testing.T, actual, path string, expect any, msg ...any) { | ||
t.Helper() | ||
v := jsonGet(t, actual, path) | ||
assert.Equal(t, expect, v, msg...) | ||
} | ||
|
||
func jsonAssertExists(t *testing.T, actual, path string, msg ...any) { | ||
t.Helper() | ||
v := jsonGet(t, actual, path) | ||
assert.NotNil(t, v, msg...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package integrationtest | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"net/url" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/rs/zerolog/log" | ||
|
||
"github.com/jcodybaker/go-shelly" | ||
"github.com/mongoose-os/mos/common/mgrpc" | ||
) | ||
|
||
func init() { | ||
flag.StringVar(&iTest.uri, "device-uri", "", "device for test") | ||
iTest.ctx = context.Background() | ||
} | ||
|
||
var iTest = struct { | ||
ctx context.Context | ||
uri string | ||
srcPath string | ||
binDir string | ||
binPath string | ||
deviceInfo *shelly.ShellyGetDeviceInfoResponse | ||
spec shelly.DeviceSpecs | ||
}{} | ||
|
||
func TestMain(m *testing.M) { | ||
if !flag.Parsed() { | ||
flag.Parse() | ||
} | ||
defer cleanup() | ||
build() | ||
cleanupURI() | ||
getDeviceInfo() | ||
os.Exit(m.Run()) | ||
} | ||
|
||
func cleanupURI() { | ||
if iTest.uri == "" { | ||
log.Fatal().Msg("the -device-uri parameter is required") | ||
} | ||
var u *url.URL | ||
if !strings.Contains(iTest.uri, "://") { | ||
iTest.uri = "http://" + iTest.uri | ||
} | ||
u, err := url.Parse(iTest.uri) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("parsing device-uri parameter") | ||
} | ||
log.Info().Str("uri.path", u.Path).Msg("using URI path") | ||
if u.Path == "" { | ||
u.Path = "/rpc" | ||
} | ||
iTest.uri = u.String() | ||
log.Info().Str("uri", iTest.uri).Msg("using URI") | ||
} | ||
|
||
func getDeviceInfo() { | ||
ctx := context.Background() | ||
c, err := mgrpc.New(ctx, iTest.uri, mgrpc.UseHTTPPost()) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("establishing connection to test device") | ||
} | ||
defer c.Disconnect(ctx) | ||
|
||
iTest.deviceInfo, _, err = (&shelly.ShellyGetDeviceInfoRequest{}).Do(ctx, c, nil) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("requesting device info") | ||
} | ||
|
||
iTest.spec, err = shelly.AppToDeviceSpecs(iTest.deviceInfo.App, iTest.deviceInfo.Profile) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("resolving device specs") | ||
} | ||
} | ||
|
||
func build() { | ||
_, file, _, ok := runtime.Caller(0) | ||
if !ok { | ||
log.Fatal().Msg("finding path of src for test") | ||
} | ||
dir := filepath.Dir(file) | ||
splitPath := strings.Split(dir, string(filepath.Separator)) | ||
if len(splitPath) < 2 { | ||
log.Fatal().Strs("path", splitPath).Msg("src directory was improbably short") | ||
} | ||
last := splitPath[len(splitPath)-1] | ||
if last != "integration_test" { | ||
log.Fatal().Msg("src directory has wrong format") | ||
} | ||
iTest.srcPath = string(filepath.Separator) + filepath.Join(splitPath[0:len(splitPath)-1]...) | ||
var err error | ||
iTest.binDir, err = os.MkdirTemp("", "shellyctl") | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("making temp dir for binary") | ||
} | ||
iTest.binPath = filepath.Join(iTest.binDir, "shellyctl") | ||
cmd := exec.CommandContext(iTest.ctx, "go", "build", "-o", iTest.binPath, iTest.srcPath) | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
log.Fatal().Err(err).Str("out", string(out)).Msg("making temp dir for binary") | ||
} | ||
} | ||
|
||
func cleanup() { | ||
if iTest.binDir != "" { | ||
os.RemoveAll(iTest.binDir) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package integrationtest | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestShellyGetDeviceInfo(t *testing.T) { | ||
out, logs, exit := run(iTest.ctx, t, true, "shelly", "get-device-info") | ||
require.Equal(t, 0, exit) | ||
t.Log(out) | ||
t.Log(logs) | ||
t.Logf("cmd exited: %d", exit) | ||
jsonAssertEqual(t, out, "$.auth_en", false) | ||
} | ||
|
||
func TestShellyGetStatus(t *testing.T) { | ||
out, logs, exit := run(iTest.ctx, t, true, "shelly", "get-status") | ||
require.Equal(t, 0, exit) | ||
t.Log(out) | ||
t.Log(logs) | ||
t.Logf("cmd exited: %d", exit) | ||
jsonAssertExists(t, out, "$.sys") | ||
jsonAssertExists(t, out, "$.cloud") | ||
if iTest.spec.Ethernet { | ||
jsonAssertExists(t, out, "$.eth") | ||
} | ||
jsonAssertExists(t, out, "$.wifi") | ||
jsonAssertExists(t, out, "$.ble") | ||
jsonAssertExists(t, out, "$.mqtt") | ||
if iTest.spec.Switches > 0 { | ||
jsonAssertExists(t, out, "$.switches") | ||
} | ||
if iTest.spec.Covers > 0 { | ||
jsonAssertExists(t, out, "$.covers") | ||
} | ||
if iTest.spec.Inputs > 0 { | ||
jsonAssertExists(t, out, "$.inputs") | ||
} | ||
if iTest.spec.Lights > 0 { | ||
jsonAssertExists(t, out, "$.lights") | ||
} | ||
} | ||
|
||
func TestShellyGetConfig(t *testing.T) { | ||
out, logs, exit := run(iTest.ctx, t, true, "shelly", "get-config") | ||
require.Equal(t, 0, exit) | ||
t.Log(out) | ||
t.Log(logs) | ||
t.Logf("cmd exited: %d", exit) | ||
jsonAssertExists(t, out, "$.sys") | ||
jsonAssertExists(t, out, "$.cloud") | ||
if iTest.spec.Ethernet { | ||
jsonAssertExists(t, out, "$.eth") | ||
} | ||
jsonAssertExists(t, out, "$.wifi") | ||
jsonAssertExists(t, out, "$.ble") | ||
jsonAssertExists(t, out, "$.mqtt") | ||
if iTest.spec.Switches > 0 { | ||
jsonAssertExists(t, out, "$.switches") | ||
} | ||
if iTest.spec.Covers > 0 { | ||
jsonAssertExists(t, out, "$.covers") | ||
} | ||
if iTest.spec.Inputs > 0 { | ||
jsonAssertExists(t, out, "$.inputs") | ||
} | ||
if iTest.spec.Lights > 0 { | ||
jsonAssertExists(t, out, "$.lights") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.