veyron/tools/mgmt/device: add support for install config override to device tool
Most of the changes are in the unit test. Added a couple more test cases to the
install test, and re-structured the test on the pattern of defining the test
cases as structs.
Change-Id: Ide79df6371a364e6ac52ad616eb84720657e0083
diff --git a/tools/mgmt/device/devicemanager_mock_test.go b/tools/mgmt/device/devicemanager_mock_test.go
index 15b0733..859613b 100644
--- a/tools/mgmt/device/devicemanager_mock_test.go
+++ b/tools/mgmt/device/devicemanager_mock_test.go
@@ -77,6 +77,7 @@
type InstallStimulus struct {
fun string
appName string
+ config device.Config
}
type InstallResponse struct {
@@ -85,7 +86,7 @@
}
func (mni *mockDeviceInvoker) Install(call ipc.ServerContext, appName string, config device.Config) (string, error) {
- ir := mni.tape.Record(InstallStimulus{"Install", appName})
+ ir := mni.tape.Record(InstallStimulus{"Install", appName, config})
r := ir.(InstallResponse)
return r.appId, r.err
}
diff --git a/tools/mgmt/device/impl.go b/tools/mgmt/device/impl.go
index 9a6aaf9..b62fb96 100644
--- a/tools/mgmt/device/impl.go
+++ b/tools/mgmt/device/impl.go
@@ -1,6 +1,7 @@
package main
import (
+ "encoding/json"
"fmt"
"v.io/core/veyron2"
@@ -16,19 +17,29 @@
Name: "install",
Short: "Install the given application.",
Long: "Install the given application.",
- ArgsName: "<device> <application>",
+ ArgsName: "<device> <application> [<config override>]",
ArgsLong: `
<device> is the veyron object name of the device manager's app service.
-<application> is the veyron object name of the application.`,
+
+<application> is the veyron object name of the application.
+
+<config override> is an optional JSON-encoded device.Config object, of the form:
+ '{"flag1":"value1","flag2":"value2"}'.`,
}
func runInstall(cmd *cmdline.Command, args []string) error {
- if expected, got := 2, len(args); expected != got {
- return cmd.UsageErrorf("install: incorrect number of arguments, expected %d, got %d", expected, got)
+ if expectedMin, expectedMax, got := 2, 3, len(args); expectedMin > got || expectedMax < got {
+ return cmd.UsageErrorf("install: incorrect number of arguments, expected between %d and %d, got %d", expectedMin, expectedMax, got)
}
deviceName, appName := args[0], args[1]
- // TODO(caprita): Add support for config override.
- appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, nil)
+ var cfg device.Config
+ if len(args) > 2 {
+ jsonConfig := args[2]
+ if err := json.Unmarshal([]byte(jsonConfig), &cfg); err != nil {
+ return fmt.Errorf("Unmarshal(%v) failed: %v", jsonConfig, err)
+ }
+ }
+ appID, err := device.ApplicationClient(deviceName).Install(gctx, appName, cfg)
if err != nil {
return fmt.Errorf("Install failed: %v", err)
}
diff --git a/tools/mgmt/device/impl_test.go b/tools/mgmt/device/impl_test.go
index 8425bec..a72c411 100644
--- a/tools/mgmt/device/impl_test.go
+++ b/tools/mgmt/device/impl_test.go
@@ -2,6 +2,7 @@
import (
"bytes"
+ "encoding/json"
"fmt"
"reflect"
"strings"
@@ -173,47 +174,81 @@
var stdout, stderr bytes.Buffer
cmd.Init(nil, &stdout, &stderr)
deviceName := naming.JoinAddressName(endpoint.String(), "")
-
- if err := cmd.Execute([]string{"install", "blech"}); err == nil {
- t.Fatalf("wrongly failed to receive a non-nil error.")
- }
- if got, expected := len(tape.Play()), 0; got != expected {
- t.Errorf("invalid call sequence. Got %v, want %v", got, expected)
- }
- tape.Rewind()
- stdout.Reset()
-
- if err := cmd.Execute([]string{"install", "blech1", "blech2", "blech3"}); err == nil {
- t.Fatalf("wrongly failed to receive a non-nil error.")
- }
- if got, expected := len(tape.Play()), 0; got != expected {
- t.Errorf("invalid call sequence. Got %v, want %v", got, expected)
- }
- tape.Rewind()
- stdout.Reset()
-
appId := "myBestAppID"
- tape.SetResponses([]interface{}{InstallResponse{
- appId: appId,
- err: nil,
- }})
- if err := cmd.Execute([]string{"install", deviceName, "myBestApp"}); err != nil {
- t.Fatalf("%v", err)
+ cfg := device.Config{"someflag": "somevalue"}
+ for i, c := range []struct {
+ args []string
+ config device.Config
+ shouldErr bool
+ tapeResponse interface{}
+ expectedTape interface{}
+ }{
+ {
+ []string{"install", "blech"},
+ nil,
+ true,
+ nil,
+ nil,
+ },
+ {
+ []string{"install", "blech1", "blech2", "blech3", "blech4"},
+ nil,
+ true,
+ nil,
+ nil,
+ },
+ {
+ []string{"install", deviceName, "myBestApp", "not-valid-json"},
+ nil,
+ true,
+ nil,
+ nil,
+ },
+ {
+ []string{"install", deviceName, "myBestApp"},
+ nil,
+ false,
+ InstallResponse{appId, nil},
+ InstallStimulus{"Install", "myBestApp", nil},
+ },
+ {
+ []string{"install", deviceName, "myBestApp"},
+ cfg,
+ false,
+ InstallResponse{appId, nil},
+ InstallStimulus{"Install", "myBestApp", cfg},
+ },
+ } {
+ tape.SetResponses([]interface{}{c.tapeResponse})
+ if c.config != nil {
+ jsonConfig, err := json.Marshal(c.config)
+ if err != nil {
+ t.Fatalf("test case %d: Marshal(%v) failed: %v", i, c.config, err)
+ }
+ c.args = append(c.args, string(jsonConfig))
+ }
+ err := cmd.Execute(c.args)
+ if c.shouldErr {
+ if err == nil {
+ t.Fatalf("test case %d: wrongly failed to receive a non-nil error.", i)
+ }
+ if got, expected := len(tape.Play()), 0; got != expected {
+ t.Errorf("test case %d: invalid call sequence. Got %v, want %v", got, expected)
+ }
+ } else {
+ if err != nil {
+ t.Fatalf("test case %d: %v", i, err)
+ }
+ if expected, got := fmt.Sprintf("Successfully installed: %q", naming.Join(deviceName, appId)), strings.TrimSpace(stdout.String()); got != expected {
+ t.Fatalf("test case %d: Unexpected output from Install. Got %q, expected %q", i, got, expected)
+ }
+ if got, expected := tape.Play(), []interface{}{c.expectedTape}; !reflect.DeepEqual(expected, got) {
+ t.Errorf("test case %d: invalid call sequence. Got %v, want %v", i, got, expected)
+ }
+ }
+ tape.Rewind()
+ stdout.Reset()
}
-
- eb := new(bytes.Buffer)
- fmt.Fprintf(eb, "Successfully installed: %q", naming.Join(deviceName, appId))
- if expected, got := eb.String(), strings.TrimSpace(stdout.String()); got != expected {
- t.Fatalf("Unexpected output from Install. Got %q, expected %q", got, expected)
- }
- expected := []interface{}{
- InstallStimulus{"Install", "myBestApp"},
- }
- if got := tape.Play(); !reflect.DeepEqual(expected, got) {
- t.Errorf("unexpected result. Got %v want %v", got, expected)
- }
- tape.Rewind()
- stdout.Reset()
}
func TestClaimCommand(t *testing.T) {