func (s *getSuite) TestCommandGetsSettedValues(c *C) { // Set a value via the `snapctl set` command _, _, err := ctlcmd.Run(s.mockContext, []string{"set", "foo=bar"}) c.Check(err, IsNil) stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "foo"}) c.Check(err, IsNil) c.Check(string(stderr), Equals, "") c.Check(string(stdout), Equals, "\"bar\"") }
func (s *getSuite) TestCommandMultipleKeys(c *C) { // Set a value via the `snapctl set` command _, _, err := ctlcmd.Run(s.mockContext, []string{"set", "test-key=test-value"}) c.Check(err, IsNil) stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "initial-key", "test-key"}) c.Check(err, IsNil) c.Check(string(stderr), Equals, "") c.Check(string(stdout), Equals, `{ "initial-key": "initial-value", "test-key": "test-value" }`) }
func (s *getSuite) TestGetTests(c *C) { for _, test := range getTests { c.Logf("Test: %s", test.args) mockHandler := hooktest.NewMockHandler() state := state.New(nil) state.Lock() task := state.NewTask("test-task", "my test task") setup := &hookstate.HookSetup{Snap: "test-snap", Revision: snap.R(1), Hook: "test-hook"} var err error mockContext, err := hookstate.NewContext(task, setup, mockHandler) c.Check(err, IsNil) // Initialize configuration t := configstate.NewTransaction(state) t.Set("test-snap", "test-key1", "test-value1") t.Set("test-snap", "test-key2", 2) t.Commit() state.Unlock() stdout, stderr, err := ctlcmd.Run(mockContext, strings.Fields(test.args)) if test.error != "" { c.Check(err, ErrorMatches, test.error) } else { c.Check(err, IsNil) c.Check(string(stderr), Equals, "") c.Check(string(stdout), Equals, test.stdout) } } }
func (s *setSuite) TestCommandSavesDeltasOnly(c *C) { // Setup an initial configuration s.mockContext.State().Lock() transaction, err := configstate.NewTransaction(s.mockContext.State()) c.Check(err, IsNil) transaction.Set("test-snap", "test-key1", "test-value1") transaction.Set("test-snap", "test-key2", "test-value2") transaction.Commit() s.mockContext.State().Unlock() stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"set", "test-key2=test-value3"}) c.Check(err, IsNil) c.Check(string(stdout), Equals, "") c.Check(string(stderr), Equals, "") // Notify the context that we're done. This should save the config. s.mockContext.Lock() defer s.mockContext.Unlock() c.Check(s.mockContext.Done(), IsNil) // Verify that the global config has been updated, but only test-key2 transaction, err = configstate.NewTransaction(s.mockContext.State()) c.Check(err, IsNil) var value string c.Check(transaction.Get("test-snap", "test-key1", &value), IsNil) c.Check(value, Equals, "test-value1") c.Check(transaction.Get("test-snap", "test-key2", &value), IsNil) c.Check(value, Equals, "test-value3") }
func (s *setSuite) TestCommand(c *C) { stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"set", "foo=bar", "baz=qux"}) c.Check(err, IsNil) c.Check(string(stdout), Equals, "") c.Check(string(stderr), Equals, "") // Verify that the previous set doesn't modify the global state s.mockContext.State().Lock() transaction, err := configstate.NewTransaction(s.mockContext.State()) s.mockContext.State().Unlock() c.Check(err, IsNil) var value string c.Check(transaction.Get("test-snap", "foo", &value), ErrorMatches, ".*snap.*has no.*configuration.*") c.Check(transaction.Get("test-snap", "baz", &value), ErrorMatches, ".*snap.*has no.*configuration.*") // Notify the context that we're done. This should save the config. s.mockContext.Lock() defer s.mockContext.Unlock() c.Check(s.mockContext.Done(), IsNil) // Verify that the global config has been updated. transaction, err = configstate.NewTransaction(s.mockContext.State()) c.Check(err, IsNil) c.Check(transaction.Get("test-snap", "foo", &value), IsNil) c.Check(value, Equals, "bar") c.Check(transaction.Get("test-snap", "baz", &value), IsNil) c.Check(value, Equals, "qux") }
func runSnapctl(c *Command, r *http.Request, user *auth.UserState) Response { var snapctlOptions client.SnapCtlOptions decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&snapctlOptions); err != nil { return BadRequest("cannot decode snapctl request: %s", err) } if len(snapctlOptions.Args) == 0 { return BadRequest("snapctl cannot run without args") } // Right now snapctl is only used for hooks. If at some point it grows // beyond that, this probably shouldn't go straight to the HookManager. context, _ := c.d.overlord.HookManager().Context(snapctlOptions.ContextID) stdout, stderr, err := ctlcmd.Run(context, snapctlOptions.Args) if err != nil { if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp { stdout = []byte(e.Error()) } else { return BadRequest("error running snapctl: %s", err) } } result := map[string]string{ "stdout": string(stdout), "stderr": string(stderr), } return SyncResponse(result, nil) }
func (s *ctlcmdSuite) TestCommandOutput(c *C) { mockCommand := ctlcmd.AddMockCommand("mock") defer ctlcmd.RemoveCommand("mock") mockCommand.FakeStdout = "test stdout" mockCommand.FakeStderr = "test stderr" stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"mock", "foo"}) c.Check(err, IsNil) c.Check(string(stdout), Equals, "test stdout") c.Check(string(stderr), Equals, "test stderr") c.Check(mockCommand.Args, DeepEquals, []string{"foo"}) }
func (s *deviceMgrSuite) TestFullDeviceRegistrationHappyPrepareDeviceHook(c *C) { r1 := devicestate.MockKeyLength(752) defer r1() mockServer := s.mockServer(c, "REQID-1") defer mockServer.Close() r2 := hookstate.MockRunHook(func(ctx *hookstate.Context, _ *tomb.Tomb) ([]byte, error) { c.Assert(ctx.HookName(), Equals, "prepare-device") // snapctl set the registration params _, _, err := ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("device-service.url=%q", mockServer.URL+"/identity/api/v1/")}) c.Assert(err, IsNil) h, err := json.Marshal(map[string]string{ "x-extra-header": "extra", }) c.Assert(err, IsNil) _, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("device-service.headers=%s", string(h))}) c.Assert(err, IsNil) _, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("registration.proposed-serial=%q", "Y9999")}) c.Assert(err, IsNil) d, err := yaml.Marshal(map[string]string{ "mac": "00:00:00:00:ff:00", }) c.Assert(err, IsNil) _, _, err = ctlcmd.Run(ctx, []string{"set", fmt.Sprintf("registration.body=%q", d)}) c.Assert(err, IsNil) return nil, nil }) defer r2() // setup state as will be done by first-boot // & have a gadget with a prepare-device hook s.state.Lock() defer s.state.Unlock() s.setupGadget(c, ` name: gadget type: gadget version: gadget hooks: prepare-device: `, "") auth.SetDevice(s.state, &auth.DeviceState{ Brand: "canonical", Model: "pc", }) // runs the whole device registration process s.state.Unlock() s.settle() s.state.Lock() var becomeOperational *state.Change for _, chg := range s.state.Changes() { if chg.Kind() == "become-operational" { becomeOperational = chg break } } c.Assert(becomeOperational, NotNil) c.Check(becomeOperational.Status().Ready(), Equals, true) c.Check(becomeOperational.Err(), IsNil) device, err := auth.Device(s.state) c.Assert(err, IsNil) c.Check(device.Brand, Equals, "canonical") c.Check(device.Model, Equals, "pc") c.Check(device.Serial, Equals, "Y9999") a, err := s.db.Find(asserts.SerialType, map[string]string{ "brand-id": "canonical", "model": "pc", "serial": "Y9999", }) c.Assert(err, IsNil) serial := a.(*asserts.Serial) var details map[string]interface{} err = yaml.Unmarshal(serial.Body(), &details) c.Assert(err, IsNil) c.Check(details, DeepEquals, map[string]interface{}{ "mac": "00:00:00:00:ff:00", }) privKey, err := s.mgr.KeypairManager().Get(serial.DeviceKey().ID()) c.Assert(err, IsNil) c.Check(privKey, NotNil) c.Check(device.KeyID, Equals, privKey.PublicKey().ID()) }
func (s *getSuite) TestCommandWithoutContext(c *C) { _, _, err := ctlcmd.Run(nil, []string{"get", "foo"}) c.Check(err, ErrorMatches, ".*cannot get without a context.*") }
func (s *getSuite) TestCommandWithNoConfig(c *C) { stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "foo"}) c.Check(err, ErrorMatches, ".*snap.*has no.*configuration option.*") c.Check(string(stderr), Equals, "") c.Check(string(stdout), Equals, "") }
func (s *getSuite) TestCommand(c *C) { stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"get", "initial-key"}) c.Check(err, IsNil) c.Check(string(stderr), Equals, "") c.Check(string(stdout), Equals, "\"initial-value\"") }
func (s *setSuite) TestInvalidArguments(c *C) { _, _, err := ctlcmd.Run(s.mockContext, []string{"set", "foo", "bar"}) c.Check(err, ErrorMatches, ".*invalid parameter.*want key=value.*") }
func (s *ctlcmdSuite) TestNonExistingCommand(c *C) { stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"foo"}) c.Check(string(stdout), Equals, "") c.Check(string(stderr), Equals, "") c.Check(err, ErrorMatches, ".*[Uu]nknown command.*") }