diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 0e140319f..1c3005d4e 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -34,6 +34,11 @@ "ImportPath": "github.com/armon/go-metrics", "Rev": "06b60999766278efd6d2b5d8418a58c3d5b99e87" }, + { + "ImportPath": "github.com/asaskevich/govalidator", + "Comment": "v2-51-g9699ab6", + "Rev": "9699ab6b38bee2e02cd3fe8b99ecf67665395c96" + }, { "ImportPath": "github.com/codegangsta/cli", "Comment": "1.2.0-26-gf7ebb76", diff --git a/cmd/snapctl/main.go b/cmd/snapctl/main.go index 2c509eccb..71ba93562 100644 --- a/cmd/snapctl/main.go +++ b/cmd/snapctl/main.go @@ -21,6 +21,7 @@ package main import ( "flag" + "fmt" "os" "sort" "time" @@ -33,6 +34,7 @@ var ( gitversion string pClient *client.Client timeFormat = time.RFC1123 + err error ) func main() { @@ -90,7 +92,11 @@ func init() { } } } - pClient = client.New(url, ver, secure) + pClient, err = client.New(url, ver, secure) + if err != nil { + fmt.Println(err) + os.Exit(1) + } resp := pClient.ListAgreements() if resp.Err == nil { commands = append(commands, tribeCommands...) diff --git a/mgmt/rest/client/client.go b/mgmt/rest/client/client.go index 95dd4ee3e..385b6405a 100644 --- a/mgmt/rest/client/client.go +++ b/mgmt/rest/client/client.go @@ -35,6 +35,8 @@ import ( "path/filepath" "strings" + "github.com/asaskevich/govalidator" + "github.com/intelsdi-x/snap/mgmt/rest/rbody" ) @@ -72,9 +74,20 @@ type Client struct { prefix string } +// Checks validity of URL +func parseURL(url string) error { + if !govalidator.IsURL(url) || !strings.HasPrefix(url, "http") { + return fmt.Errorf("URL %s is not in the format of http(s)://:", url) + } + return nil +} + // New returns a pointer to a snap api client // if ver is an empty string, v1 is used by default -func New(url, ver string, insecure bool) *Client { +func New(url, ver string, insecure bool) (*Client, error) { + if err := parseURL(url); err != nil { + return nil, err + } if ver == "" { ver = "v1" } @@ -91,8 +104,7 @@ func New(url, ver string, insecure bool) *Client { }, } c.prefix = url + "/" + ver - // TODO (danielscottt): assert that path is valid and target is available - return c + return c, nil } // String returns the string representation of the content type given a content number. diff --git a/mgmt/rest/client/client_config_func_test.go b/mgmt/rest/client/client_config_func_test.go index 898e226a0..3aef8bb8f 100644 --- a/mgmt/rest/client/client_config_func_test.go +++ b/mgmt/rest/client/client_config_func_test.go @@ -31,228 +31,231 @@ import ( func TestSnapClientConfig(t *testing.T) { uri := startAPI() CompressUpload = false - c := New(uri, "v1", true) - Convey("When no config is set", t, func() { - Convey("Get global config", func() { - res := c.GetPluginConfig("", "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) - }) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) - }) - Convey("Get config for all processors", func() { - res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) - }) - Convey("Get config for all publishers", func() { - res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) - }) - }) - Convey("A global plugin config is set", t, func() { - res := c.SetPluginConfig("", "", "", "password", ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - So(res.Err, ShouldBeNil) - So(res.SetPluginConfigItem, ShouldNotBeNil) - So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 1) - So(res.SetPluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - Convey("Get global config", func() { - res := c.GetPluginConfig("", "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - }) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - }) - Convey("Get config for all processors", func() { - res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + c, err := New(uri, "v1", true) + Convey("Client should be created", t, func() { + So(err, ShouldBeNil) + Convey("When no config is set", func() { + Convey("Get global config", func() { + res := c.GetPluginConfig("", "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) + }) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) + }) + Convey("Get config for all processors", func() { + res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) + }) + Convey("Get config for all publishers", func() { + res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 0) + }) }) - Convey("Get config for all publishers", func() { - res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + Convey("A global plugin config is set", func() { + res := c.SetPluginConfig("", "", "", "password", ctypes.ConfigValueStr{Value: "p@ssw0rd"}) So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + So(res.SetPluginConfigItem, ShouldNotBeNil) + So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 1) + So(res.SetPluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + Convey("Get global config", func() { + res := c.GetPluginConfig("", "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + }) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + }) + Convey("Get config for all processors", func() { + res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + }) + Convey("Get config for all publishers", func() { + res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + }) }) - }) - Convey("A plugin config item for a specific type of plugin is added", t, func() { - res := c.SetPluginConfig(core.CollectorPluginType.String(), "", "", "user", ctypes.ConfigValueStr{Value: "john"}) - So(res.Err, ShouldBeNil) - So(res.SetPluginConfigItem, ShouldNotBeNil) - So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 2) - So(res.SetPluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.SetPluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - Convey("Get global config", func() { - res := c.GetPluginConfig("", "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + Convey("A plugin config item for a specific type of plugin is added", func() { + res := c.SetPluginConfig(core.CollectorPluginType.String(), "", "", "user", ctypes.ConfigValueStr{Value: "john"}) So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + So(res.SetPluginConfigItem, ShouldNotBeNil) + So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 2) + So(res.SetPluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.SetPluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + Convey("Get global config", func() { + res := c.GetPluginConfig("", "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + }) + Convey("Get config for all processors", func() { + res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all publishers", func() { + res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) }) - Convey("Get config for all processors", func() { - res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for all publishers", func() { - res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - }) - Convey("A plugin config item for a specific type and name of a plugin is added", t, func() { - res := c.SetPluginConfig(core.CollectorPluginType.String(), "test", "", "foo", ctypes.ConfigValueStr{Value: "bar"}) - So(res.Err, ShouldBeNil) - So(res.SetPluginConfigItem, ShouldNotBeNil) - So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 3) - Convey("Get global config", func() { - res := c.GetPluginConfig("", "", "") + Convey("A plugin config item for a specific type and name of a plugin is added", func() { + res := c.SetPluginConfig(core.CollectorPluginType.String(), "test", "", "foo", ctypes.ConfigValueStr{Value: "bar"}) So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + So(res.SetPluginConfigItem, ShouldNotBeNil) + So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 3) + Convey("Get global config", func() { + res := c.GetPluginConfig("", "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) + }) + Convey("Get config for all processors", func() { + res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all publishers", func() { + res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for the 'test' collector", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 3) + }) }) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) - }) - Convey("Get config for all processors", func() { - res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for all publishers", func() { - res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for the 'test' collector", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 3) - }) - }) - Convey("A plugin config item for a specific type, name and version of a plugin is added", t, func() { - res := c.SetPluginConfig(core.CollectorPluginType.String(), "test", "1", "go", ctypes.ConfigValueStr{Value: "pher"}) - So(res.Err, ShouldBeNil) - So(res.SetPluginConfigItem, ShouldNotBeNil) - So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 4) - Convey("Get global config", func() { - res := c.GetPluginConfig("", "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + Convey("A plugin config item for a specific type, name and version of a plugin is added", func() { + res := c.SetPluginConfig(core.CollectorPluginType.String(), "test", "1", "go", ctypes.ConfigValueStr{Value: "pher"}) So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) + So(res.SetPluginConfigItem, ShouldNotBeNil) + So(len(res.SetPluginConfigItem.Table()), ShouldEqual, 4) + Convey("Get global config", func() { + res := c.GetPluginConfig("", "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) + }) + Convey("Get config for all processors", func() { + res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for all publishers", func() { + res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for the version 1 'test' collector plugin", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) + So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 4) + }) }) - Convey("Get config for all processors", func() { - res := c.GetPluginConfig(core.ProcessorPluginType.String(), "", "") + Convey("A global plugin config item is removed", func() { + res := c.DeletePluginConfig("", "", "", "password") So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + So(res.DeletePluginConfigItem, ShouldNotBeNil) + So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 0) + Convey("Get config for all collectors", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) + Convey("Get config for the version 1 'test' collector plugin", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) + So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 3) + }) }) - Convey("Get config for all publishers", func() { - res := c.GetPluginConfig(core.PublisherPluginType.String(), "", "") + Convey("A plugin config item for a specific type of a plugin is removed", func() { + res := c.DeletePluginConfig(core.CollectorPluginType.String(), "", "", "user") So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + So(res.DeletePluginConfigItem, ShouldNotBeNil) + So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 0) + Convey("Get config for the version 1 'test' collector plugin", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) + }) }) - Convey("Get config for the version 1 'test' collector plugin", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.PluginConfigItem.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"}) - So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 4) - }) - }) - Convey("A global plugin config item is removed", t, func() { - res := c.DeletePluginConfig("", "", "", "password") - So(res.Err, ShouldBeNil) - So(res.DeletePluginConfigItem, ShouldNotBeNil) - So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 0) - Convey("Get config for all collectors", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "", "") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) - }) - Convey("Get config for the version 1 'test' collector plugin", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"}) - So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 3) - }) - }) - Convey("A plugin config item for a specific type of a plugin is removed", t, func() { - res := c.DeletePluginConfig(core.CollectorPluginType.String(), "", "", "user") - So(res.Err, ShouldBeNil) - So(res.DeletePluginConfigItem, ShouldNotBeNil) - So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 0) - Convey("Get config for the version 1 'test' collector plugin", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") - So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - So(res.PluginConfigItem.Table()["go"], ShouldResemble, ctypes.ConfigValueStr{Value: "pher"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 2) - }) - }) - Convey("A plugin config item for a specific type and version of a plugin is removed", t, func() { - res := c.DeletePluginConfig(core.CollectorPluginType.String(), "test", "1", "go") - So(res.Err, ShouldBeNil) - So(res.DeletePluginConfigItem, ShouldNotBeNil) - So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 1) - So(res.DeletePluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - Convey("Get config for the version 1 'test' collector plugin", func() { - res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") + Convey("A plugin config item for a specific type and version of a plugin is removed", func() { + res := c.DeletePluginConfig(core.CollectorPluginType.String(), "test", "1", "go") So(res.Err, ShouldBeNil) - So(res.PluginConfigItem, ShouldNotBeNil) - So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) - So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + So(res.DeletePluginConfigItem, ShouldNotBeNil) + So(len(res.DeletePluginConfigItem.Table()), ShouldEqual, 1) + So(res.DeletePluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + Convey("Get config for the version 1 'test' collector plugin", func() { + res := c.GetPluginConfig(core.CollectorPluginType.String(), "test", "1") + So(res.Err, ShouldBeNil) + So(res.PluginConfigItem, ShouldNotBeNil) + So(res.PluginConfigItem.Table()["foo"], ShouldResemble, ctypes.ConfigValueStr{Value: "bar"}) + So(len(res.PluginConfigItem.Table()), ShouldEqual, 1) + }) }) }) } diff --git a/mgmt/rest/client/client_func_test.go b/mgmt/rest/client/client_func_test.go index 98b1f97bc..cac226dda 100644 --- a/mgmt/rest/client/client_func_test.go +++ b/mgmt/rest/client/client_func_test.go @@ -50,6 +50,10 @@ var ( DIRECTORY_PATH = []string{SNAP_PATH + "/plugin/"} NextPort = 45000 + + p1 *LoadPluginResult + p2 *LoadPluginResult + p3 *LoadPluginResult ) func getWMFromSample(sample string) *wmap.WorkflowMap { @@ -96,403 +100,436 @@ func TestSnapClient(t *testing.T) { CompressUpload = false uri := startAPI() - c := New(uri, "v1", true) + c, cerr := New(uri, "v1", true) wf := getWMFromSample("1.json") sch := &Schedule{Type: "simple", Interval: "1s"} uuid := uuid.New() - Convey("Testing API after startup", t, func() { - Convey("empty version", func() { - c := New(uri, "", true) - So(c.Version, ShouldEqual, "v1") - }) - Convey("no loaded plugins", func() { - p := c.GetPlugins(false) - p2 := c.GetPlugins(true) - - So(p.Err, ShouldBeNil) - So(p2.Err, ShouldBeNil) - So(len(p.LoadedPlugins), ShouldEqual, 0) - So(p.AvailablePlugins, ShouldBeEmpty) - So(len(p2.LoadedPlugins), ShouldEqual, 0) - So(p2.AvailablePlugins, ShouldBeEmpty) - - _, err := c.pluginUploadRequest([]string{""}) - So(err, ShouldNotBeNil) - So(err.Error(), ShouldEqual, "stat : no such file or directory") - }) - Convey("empty catalog", func() { - m := c.GetMetricCatalog() - So(m.Err, ShouldBeNil) - So(m.Len(), ShouldEqual, 0) - }) - Convey("load directory error", func() { - p := c.LoadPlugin(DIRECTORY_PATH) - So(p.Err, ShouldNotBeNil) - So(p.LoadedPlugins, ShouldBeEmpty) - So(p.Err.Error(), ShouldEqual, "Provided plugin path is a directory not file") - }) - Convey("unknown task", func() { - Convey("GetTask/GetTasks", func() { - t1 := c.GetTask(uuid) - t2 := c.GetTasks() - So(t1.Err, ShouldNotBeNil) - So(t2.Err, ShouldBeNil) + Convey("Client should exist", t, func() { + So(cerr, ShouldBeNil) + Convey("Testing API after startup", func() { + Convey("empty version", func() { + c, err := New(uri, "", true) + So(err, ShouldBeNil) + So(c.Version, ShouldEqual, "v1") + }) + Convey("no loaded plugins", func() { + p := c.GetPlugins(false) + p2 := c.GetPlugins(true) + + So(p.Err, ShouldBeNil) + So(p2.Err, ShouldBeNil) + So(len(p.LoadedPlugins), ShouldEqual, 0) + So(p.AvailablePlugins, ShouldBeEmpty) + So(len(p2.LoadedPlugins), ShouldEqual, 0) + So(p2.AvailablePlugins, ShouldBeEmpty) + + _, err := c.pluginUploadRequest([]string{""}) + So(err, ShouldNotBeNil) + So(err.Error(), ShouldEqual, "stat : no such file or directory") }) - Convey("StopTask", func() { - t1 := c.StopTask(uuid) - So(t1.Err, ShouldNotBeNil) - So(t1.Err.Error(), ShouldEqual, fmt.Sprintf("error 0: Task not found: ID(%s) ", uuid)) + Convey("empty catalog", func() { + m := c.GetMetricCatalog() + So(m.Err, ShouldBeNil) + So(m.Len(), ShouldEqual, 0) }) - Convey("RemoveTask", func() { - t1 := c.RemoveTask(uuid) - So(t1.Err, ShouldNotBeNil) - So(t1.Err.Error(), ShouldEqual, fmt.Sprintf("Task not found: ID(%s)", uuid)) + Convey("load directory error", func() { + p := c.LoadPlugin(DIRECTORY_PATH) + So(p.Err, ShouldNotBeNil) + So(p.LoadedPlugins, ShouldBeEmpty) + So(p.Err.Error(), ShouldEqual, "Provided plugin path is a directory not file") }) - Convey("invalid task (missing metric)", func() { - tt := c.CreateTask(sch, wf, "baron", "", true) - So(tt.Err, ShouldNotBeNil) - So(tt.Err.Error(), ShouldContainSubstring, "Metric not found: /intel/mock/foo") + Convey("unknown task", func() { + Convey("GetTask/GetTasks", func() { + t1 := c.GetTask(uuid) + t2 := c.GetTasks() + So(t1.Err, ShouldNotBeNil) + So(t2.Err, ShouldBeNil) + }) + Convey("StopTask", func() { + t1 := c.StopTask(uuid) + So(t1.Err, ShouldNotBeNil) + So(t1.Err.Error(), ShouldEqual, fmt.Sprintf("error 0: Task not found: ID(%s) ", uuid)) + }) + Convey("RemoveTask", func() { + t1 := c.RemoveTask(uuid) + So(t1.Err, ShouldNotBeNil) + So(t1.Err.Error(), ShouldEqual, fmt.Sprintf("Task not found: ID(%s)", uuid)) + }) + Convey("invalid task (missing metric)", func() { + tt := c.CreateTask(sch, wf, "baron", "", true) + So(tt.Err, ShouldNotBeNil) + So(tt.Err.Error(), ShouldContainSubstring, "Metric not found: /intel/mock/foo") + }) }) }) }) CompressUpload = true - p1 := c.LoadPlugin(MOCK_PLUGIN_PATH1) + if cerr == nil { + p1 = c.LoadPlugin(MOCK_PLUGIN_PATH1) + } CompressUpload = false - Convey("single plugin loaded", t, func() { - Convey("an error should not be received loading a plugin", func() { - So(c.Version, ShouldEqual, "v1") - - So(p1.Err, ShouldBeNil) - So(p1.LoadedPlugins, ShouldNotBeEmpty) - So(p1.LoadedPlugins[0].Name, ShouldEqual, "mock") - So(p1.LoadedPlugins[0].Version, ShouldEqual, 1) - So(p1.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) - }) - Convey("there should be one loaded plugin", func() { - p := c.GetPlugins(false) - So(p.Err, ShouldBeNil) - So(len(p.LoadedPlugins), ShouldEqual, 1) - So(p.AvailablePlugins, ShouldBeEmpty) - }) - Convey("invalid task (missing publisher)", func() { - tf := c.CreateTask(sch, wf, "baron", "", false) - So(tf.Err, ShouldNotBeNil) - So(tf.Err.Error(), ShouldContainSubstring, "Plugin not found: type(publisher) name(file)") - }) - Convey("plugin already loaded", func() { - p1 := c.LoadPlugin(MOCK_PLUGIN_PATH1) - So(p1.Err, ShouldNotBeNil) - So(p1.Err.Error(), ShouldEqual, "plugin is already loaded") + Convey("Client should exist", t, func() { + So(cerr, ShouldBeNil) + Convey("single plugin loaded", func() { + Convey("an error should not be received loading a plugin", func() { + So(c.Version, ShouldEqual, "v1") + + So(p1, ShouldNotBeNil) + So(p1.Err, ShouldBeNil) + So(p1.LoadedPlugins, ShouldNotBeEmpty) + So(p1.LoadedPlugins[0].Name, ShouldEqual, "mock") + So(p1.LoadedPlugins[0].Version, ShouldEqual, 1) + So(p1.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) + }) + Convey("there should be one loaded plugin", func() { + p := c.GetPlugins(false) + So(p.Err, ShouldBeNil) + So(len(p.LoadedPlugins), ShouldEqual, 1) + So(p.AvailablePlugins, ShouldBeEmpty) + }) + Convey("invalid task (missing publisher)", func() { + tf := c.CreateTask(sch, wf, "baron", "", false) + So(tf.Err, ShouldNotBeNil) + So(tf.Err.Error(), ShouldContainSubstring, "Plugin not found: type(publisher) name(file)") + }) + Convey("plugin already loaded", func() { + p1 := c.LoadPlugin(MOCK_PLUGIN_PATH1) + So(p1.Err, ShouldNotBeNil) + So(p1.Err.Error(), ShouldEqual, "plugin is already loaded") + }) }) }) - p2 := c.LoadPlugin(MOCK_PLUGIN_PATH2) - Convey("loading second plugin", t, func() { - Convey("an error should not be received loading second plugin", func() { - So(p2.Err, ShouldBeNil) - So(p2.LoadedPlugins, ShouldNotBeEmpty) - So(p2.LoadedPlugins[0].Name, ShouldEqual, "mock") - So(p2.LoadedPlugins[0].Version, ShouldEqual, 2) - So(p2.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) - }) - Convey("there should be two loaded plugins", func() { - p := c.GetPlugins(false) - So(p.Err, ShouldBeNil) - So(len(p.LoadedPlugins), ShouldEqual, 2) - So(p.AvailablePlugins, ShouldBeEmpty) - }) - }) - Convey("Metrics", t, func() { - Convey("MetricCatalog", func() { - m := c.GetMetricCatalog() - So(m.Err, ShouldBeNil) - So(m.Len(), ShouldEqual, 6) - So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/*/baz") - So(m.Catalog[0].Version, ShouldEqual, 1) - So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/*/baz") - So(m.Catalog[1].Version, ShouldEqual, 2) - So(m.Catalog[2].Namespace, ShouldEqual, "/intel/mock/bar") - So(m.Catalog[2].Version, ShouldEqual, 1) - So(m.Catalog[3].Namespace, ShouldEqual, "/intel/mock/bar") - So(m.Catalog[3].Version, ShouldEqual, 2) - So(m.Catalog[4].Namespace, ShouldEqual, "/intel/mock/foo") - So(m.Catalog[4].Version, ShouldEqual, 1) - So(m.Catalog[5].Namespace, ShouldEqual, "/intel/mock/foo") - So(m.Catalog[5].Version, ShouldEqual, 2) - }) - Convey("FetchMetrics", func() { - Convey("leaf metric all versions", func() { - m := c.FetchMetrics("/intel/mock/bar/*", 0) - So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/bar") - So(m.Catalog[0].Version, ShouldEqual, 1) - So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/bar") - So(m.Catalog[1].Version, ShouldEqual, 2) + if cerr == nil { + p2 = c.LoadPlugin(MOCK_PLUGIN_PATH2) + } + Convey("Client should exist", t, func() { + So(cerr, ShouldBeNil) + Convey("loading second plugin", func() { + Convey("an error should not be received loading second plugin", func() { + So(p2, ShouldNotBeNil) + So(p2.Err, ShouldBeNil) + So(p2.LoadedPlugins, ShouldNotBeEmpty) + So(p2.LoadedPlugins[0].Name, ShouldEqual, "mock") + So(p2.LoadedPlugins[0].Version, ShouldEqual, 2) + So(p2.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) }) - Convey("version 2 leaf metric", func() { - m := c.FetchMetrics("/intel/mock/bar/*", 2) - So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/bar") - So(m.Catalog[0].Version, ShouldEqual, 2) + Convey("there should be two loaded plugins", func() { + p := c.GetPlugins(false) + So(p.Err, ShouldBeNil) + So(len(p.LoadedPlugins), ShouldEqual, 2) + So(p.AvailablePlugins, ShouldBeEmpty) }) - Convey("version 2 non-leaf metrics", func() { - m := c.FetchMetrics("/intel/mock/*", 2) + }) + Convey("Metrics", func() { + Convey("MetricCatalog", func() { + m := c.GetMetricCatalog() + So(m.Err, ShouldBeNil) + So(m.Len(), ShouldEqual, 6) So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/*/baz") - So(m.Catalog[0].Version, ShouldEqual, 2) - So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[0].Version, ShouldEqual, 1) + So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/*/baz") So(m.Catalog[1].Version, ShouldEqual, 2) - So(m.Catalog[2].Namespace, ShouldEqual, "/intel/mock/foo") - So(m.Catalog[2].Version, ShouldEqual, 2) + So(m.Catalog[2].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[2].Version, ShouldEqual, 1) + So(m.Catalog[3].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[3].Version, ShouldEqual, 2) + So(m.Catalog[4].Namespace, ShouldEqual, "/intel/mock/foo") + So(m.Catalog[4].Version, ShouldEqual, 1) + So(m.Catalog[5].Namespace, ShouldEqual, "/intel/mock/foo") + So(m.Catalog[5].Version, ShouldEqual, 2) + }) + Convey("FetchMetrics", func() { + Convey("leaf metric all versions", func() { + m := c.FetchMetrics("/intel/mock/bar/*", 0) + So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[0].Version, ShouldEqual, 1) + So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[1].Version, ShouldEqual, 2) + }) + Convey("version 2 leaf metric", func() { + m := c.FetchMetrics("/intel/mock/bar/*", 2) + So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[0].Version, ShouldEqual, 2) + }) + Convey("version 2 non-leaf metrics", func() { + m := c.FetchMetrics("/intel/mock/*", 2) + So(m.Catalog[0].Namespace, ShouldEqual, "/intel/mock/*/baz") + So(m.Catalog[0].Version, ShouldEqual, 2) + So(m.Catalog[1].Namespace, ShouldEqual, "/intel/mock/bar") + So(m.Catalog[1].Version, ShouldEqual, 2) + So(m.Catalog[2].Namespace, ShouldEqual, "/intel/mock/foo") + So(m.Catalog[2].Version, ShouldEqual, 2) + }) }) }) }) - p3 := c.LoadPlugin(FILE_PLUGIN_PATH) - Convey("publisher plugin loaded", t, func() { - Convey("an error should not be received loading publisher plugin", func() { - So(p3.Err, ShouldBeNil) - So(p3.LoadedPlugins, ShouldNotBeEmpty) - So(p3.LoadedPlugins[0].Name, ShouldEqual, "file") - So(p3.LoadedPlugins[0].Version, ShouldEqual, 3) - So(p3.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) - }) - Convey("there should be three loaded plugins", func() { - p := c.GetPlugins(false) - So(p.Err, ShouldBeNil) - So(len(p.LoadedPlugins), ShouldEqual, 3) - So(p.AvailablePlugins, ShouldBeEmpty) - }) - }) - - Convey("Tasks", t, func() { - Convey("Passing a bad task manifest", func() { - wfb := getWMFromSample("bad.json") - ttb := c.CreateTask(sch, wfb, "bad", "", true) - So(ttb.Err, ShouldNotBeNil) - }) - - tf := c.CreateTask(sch, wf, "baron", "", false) - Convey("valid task not started on creation", func() { - So(tf.Err, ShouldBeNil) - So(tf.Name, ShouldEqual, "baron") - So(tf.State, ShouldEqual, "Stopped") - - // method not allowed - rsp, err := c.do("POST", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON) //case len(body) == 0 - So(rsp, ShouldBeNil) - So(err, ShouldNotBeNil) - b := make([]byte, 5) - rsp2, err2 := c.do("POST", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON, b) //case len(body) != 0 - So(rsp2, ShouldBeNil) - So(err2, ShouldNotBeNil) - - Convey("GetTasks", func() { - t1 := c.GetTasks() - So(t1.Err, ShouldBeNil) - t2 := c.GetTask(tf.ID) - So(t2.Err, ShouldBeNil) + if cerr == nil { + p3 = c.LoadPlugin(FILE_PLUGIN_PATH) + } + Convey("Client should exist", t, func() { + So(cerr, ShouldBeNil) + Convey("publisher plugin loaded", func() { + Convey("an error should not be received loading publisher plugin", func() { + So(p3, ShouldNotBeNil) + So(p3.Err, ShouldBeNil) + So(p3.LoadedPlugins, ShouldNotBeEmpty) + So(p3.LoadedPlugins[0].Name, ShouldEqual, "file") + So(p3.LoadedPlugins[0].Version, ShouldEqual, 3) + So(p3.LoadedPlugins[0].LoadedTime().Unix(), ShouldBeLessThanOrEqualTo, time.Now().Unix()) }) - Convey("StopTask", func() { - t1 := c.StopTask(tf.ID) - So(t1.Err, ShouldNotBeNil) - So(t1.Err.Error(), ShouldEqual, "error 0: Task is already stopped. ") + Convey("there should be three loaded plugins", func() { + p := c.GetPlugins(false) + So(p.Err, ShouldBeNil) + So(len(p.LoadedPlugins), ShouldEqual, 3) + So(p.AvailablePlugins, ShouldBeEmpty) }) - Convey("StartTask", func() { - t1 := c.StartTask(tf.ID) - So(t1.Err, ShouldBeNil) - So(t1.ID, ShouldEqual, tf.ID) + }) + + Convey("Tasks", func() { + Convey("Passing a bad task manifest", func() { + wfb := getWMFromSample("bad.json") + ttb := c.CreateTask(sch, wfb, "bad", "", true) + So(ttb.Err, ShouldNotBeNil) }) - Convey("RemoveTask", func() { - t1 := c.RemoveTask(tf.ID) - So(t1.Err, ShouldBeNil) - So(t1.ID, ShouldEqual, tf.ID) + tf := c.CreateTask(sch, wf, "baron", "", false) + Convey("valid task not started on creation", func() { + So(tf.Err, ShouldBeNil) + So(tf.Name, ShouldEqual, "baron") + So(tf.State, ShouldEqual, "Stopped") + + // method not allowed + rsp, err := c.do("POST", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON) //case len(body) == 0 + So(rsp, ShouldBeNil) + So(err, ShouldNotBeNil) b := make([]byte, 5) - rsp, err := c.do("DELETE", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON, b) //case len(body) != 0 - So(rsp, ShouldNotBeNil) - So(err, ShouldBeNil) + rsp2, err2 := c.do("POST", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON, b) //case len(body) != 0 + So(rsp2, ShouldBeNil) + So(err2, ShouldNotBeNil) + + Convey("GetTasks", func() { + t1 := c.GetTasks() + So(t1.Err, ShouldBeNil) + t2 := c.GetTask(tf.ID) + So(t2.Err, ShouldBeNil) + }) + Convey("StopTask", func() { + t1 := c.StopTask(tf.ID) + So(t1.Err, ShouldNotBeNil) + So(t1.Err.Error(), ShouldEqual, "error 0: Task is already stopped. ") + }) + Convey("StartTask", func() { + t1 := c.StartTask(tf.ID) + So(t1.Err, ShouldBeNil) + So(t1.ID, ShouldEqual, tf.ID) + }) + Convey("RemoveTask", func() { + t1 := c.RemoveTask(tf.ID) + So(t1.Err, ShouldBeNil) + So(t1.ID, ShouldEqual, tf.ID) + + b := make([]byte, 5) + rsp, err := c.do("DELETE", fmt.Sprintf("/tasks/%v", tf.ID), ContentTypeJSON, b) //case len(body) != 0 + So(rsp, ShouldNotBeNil) + So(err, ShouldBeNil) + }) }) - }) - tt := c.CreateTask(sch, wf, "baron", "", true) - Convey("valid task started on creation", func() { - So(tt.Err, ShouldBeNil) - So(tt.Name, ShouldEqual, "baron") - So(tt.State, ShouldEqual, "Running") - - // method not allowed - rsp, err := c.do("POST", fmt.Sprintf("/tasks/%v", tt.ID), ContentTypeJSON) //case len(body) == 0 - So(rsp, ShouldBeNil) - So(err, ShouldNotBeNil) - b := make([]byte, 5) - rsp2, err2 := c.do("POST", fmt.Sprintf("/tasks/%v", tt.ID), ContentTypeJSON, b) //case len(body) != 0 - So(rsp2, ShouldBeNil) - So(err2, ShouldNotBeNil) - - Convey("GetTasks", func() { - t1 := c.GetTasks() - So(t1.Err, ShouldBeNil) - t2 := c.GetTask(tt.ID) - So(t2.Err, ShouldBeNil) - }) - Convey("StartTask", func() { - t1 := c.StartTask(tt.ID) - So(t1.Err, ShouldNotBeNil) - So(t1.Err.Error(), ShouldEqual, "error 0: Task is already running. ") - t2 := c.StartTask(tt.ID) - So(t2.Err, ShouldNotBeNil) - So(t2.Err.Error(), ShouldEqual, "error 0: Task is already running. ") - }) - Convey("RemoveTask", func() { - t1 := c.RemoveTask(tt.ID) - So(t1.Err, ShouldNotBeNil) - So(t1.Err.Error(), ShouldEqual, "Task must be stopped") - }) - Convey("StopTask", func() { - t1 := c.StopTask(tt.ID) - So(t1.Err, ShouldBeNil) - So(t1.ID, ShouldEqual, tt.ID) - //try stopping again to make sure channel is closed - t2 := c.StopTask(tt.ID) - So(t2.Err, ShouldNotBeNil) - So(t2.Err.Error(), ShouldEqual, "error 0: Task is already stopped. ") + tt := c.CreateTask(sch, wf, "baron", "", true) + Convey("valid task started on creation", func() { + So(tt.Err, ShouldBeNil) + So(tt.Name, ShouldEqual, "baron") + So(tt.State, ShouldEqual, "Running") + // method not allowed + rsp, err := c.do("POST", fmt.Sprintf("/tasks/%v", tt.ID), ContentTypeJSON) //case len(body) == 0 + So(rsp, ShouldBeNil) + So(err, ShouldNotBeNil) b := make([]byte, 5) - rsp, err := c.do("PUT", fmt.Sprintf("/tasks/%v/stop", tt.ID), ContentTypeJSON, b) - So(rsp, ShouldNotBeNil) - So(err, ShouldBeNil) - }) - Convey("enable a stopped task", func() { - et := c.EnableTask(tt.ID) - So(et.Err, ShouldNotBeNil) - So(et.Err.Error(), ShouldEqual, "Task must be disabled") - }) - Convey("WatchTasks", func() { - Convey("invalid task ID", func() { - rest.StreamingBufferWindow = 0.01 - - type ea struct { - events []string - sync.Mutex - } - - a := new(ea) - r := c.WatchTask("1") - - wait := make(chan struct{}) - go func() { - for { - select { - case e := <-r.EventChan: - a.Lock() - a.events = append(a.events, e.EventType) - if len(a.events) == 5 { - r.Close() + rsp2, err2 := c.do("POST", fmt.Sprintf("/tasks/%v", tt.ID), ContentTypeJSON, b) //case len(body) != 0 + So(rsp2, ShouldBeNil) + So(err2, ShouldNotBeNil) + + Convey("GetTasks", func() { + t1 := c.GetTasks() + So(t1.Err, ShouldBeNil) + t2 := c.GetTask(tt.ID) + So(t2.Err, ShouldBeNil) + }) + Convey("StartTask", func() { + t1 := c.StartTask(tt.ID) + So(t1.Err, ShouldNotBeNil) + So(t1.Err.Error(), ShouldEqual, "error 0: Task is already running. ") + t2 := c.StartTask(tt.ID) + So(t2.Err, ShouldNotBeNil) + So(t2.Err.Error(), ShouldEqual, "error 0: Task is already running. ") + }) + Convey("RemoveTask", func() { + t1 := c.RemoveTask(tt.ID) + So(t1.Err, ShouldNotBeNil) + So(t1.Err.Error(), ShouldEqual, "Task must be stopped") + }) + Convey("StopTask", func() { + t1 := c.StopTask(tt.ID) + So(t1.Err, ShouldBeNil) + So(t1.ID, ShouldEqual, tt.ID) + //try stopping again to make sure channel is closed + t2 := c.StopTask(tt.ID) + So(t2.Err, ShouldNotBeNil) + So(t2.Err.Error(), ShouldEqual, "error 0: Task is already stopped. ") + + b := make([]byte, 5) + rsp, err := c.do("PUT", fmt.Sprintf("/tasks/%v/stop", tt.ID), ContentTypeJSON, b) + So(rsp, ShouldNotBeNil) + So(err, ShouldBeNil) + }) + Convey("enable a stopped task", func() { + et := c.EnableTask(tt.ID) + So(et.Err, ShouldNotBeNil) + So(et.Err.Error(), ShouldEqual, "Task must be disabled") + }) + Convey("WatchTasks", func() { + Convey("invalid task ID", func() { + rest.StreamingBufferWindow = 0.01 + + type ea struct { + events []string + sync.Mutex + } + + a := new(ea) + r := c.WatchTask("1") + + wait := make(chan struct{}) + go func() { + for { + select { + case e := <-r.EventChan: + a.Lock() + a.events = append(a.events, e.EventType) + if len(a.events) == 5 { + r.Close() + } + a.Unlock() + case <-r.DoneChan: + close(wait) + return } - a.Unlock() - case <-r.DoneChan: - close(wait) - return } + }() + <-wait + So(r.Err.Error(), ShouldEqual, "Task not found: ID(1)") + }) + Convey("event stream", func() { + rest.StreamingBufferWindow = 0.01 + sch := &Schedule{Type: "simple", Interval: "100ms"} + tf := c.CreateTask(sch, wf, "baron", "", false) + + type ea struct { + events []string + sync.Mutex } - }() - <-wait - So(r.Err.Error(), ShouldEqual, "Task not found: ID(1)") - }) - Convey("event stream", func() { - rest.StreamingBufferWindow = 0.01 - sch := &Schedule{Type: "simple", Interval: "100ms"} - tf := c.CreateTask(sch, wf, "baron", "", false) - - type ea struct { - events []string - sync.Mutex - } - - a := new(ea) - r := c.WatchTask(tf.ID) - wait := make(chan struct{}) - go func() { - for { - select { - case e := <-r.EventChan: - a.Lock() - a.events = append(a.events, e.EventType) - if len(a.events) == 5 { - r.Close() + + a := new(ea) + r := c.WatchTask(tf.ID) + wait := make(chan struct{}) + go func() { + for { + select { + case e := <-r.EventChan: + a.Lock() + a.events = append(a.events, e.EventType) + if len(a.events) == 5 { + r.Close() + } + a.Unlock() + case <-r.DoneChan: + close(wait) + return } - a.Unlock() - case <-r.DoneChan: - close(wait) - return } + }() + startResp := c.StartTask(tf.ID) + So(startResp.Err, ShouldBeNil) + <-wait + a.Lock() + So(len(a.events), ShouldEqual, 5) + a.Unlock() + So(a.events[0], ShouldEqual, "task-started") + for x := 2; x <= 4; x++ { + So(a.events[x], ShouldEqual, "metric-event") } - }() - startResp := c.StartTask(tf.ID) - So(startResp.Err, ShouldBeNil) - <-wait - a.Lock() - So(len(a.events), ShouldEqual, 5) - a.Unlock() - So(a.events[0], ShouldEqual, "task-started") - for x := 2; x <= 4; x++ { - So(a.events[x], ShouldEqual, "metric-event") - } + }) }) }) }) - }) - Convey("UnloadPlugin", t, func() { - Convey("unload unknown plugin", func() { - p := c.UnloadPlugin("not a type", "foo", 3) - So(p.Err, ShouldNotBeNil) - So(p.Err.Error(), ShouldEqual, "plugin not found") - }) - Convey("unload one of multiple", func() { - p1 := c.GetPlugins(false) - So(p1.Err, ShouldBeNil) - So(len(p1.LoadedPlugins), ShouldEqual, 3) - - p2 := c.UnloadPlugin("collector", "mock", 2) - So(p2.Err, ShouldBeNil) - So(p2.Name, ShouldEqual, "mock") - So(p2.Version, ShouldEqual, 2) - So(p2.Type, ShouldEqual, "collector") - - p3 := c.UnloadPlugin("publisher", "file", 3) - So(p3.Err, ShouldBeNil) - So(p3.Name, ShouldEqual, "file") - So(p3.Version, ShouldEqual, 3) - So(p3.Type, ShouldEqual, "publisher") - }) - Convey("unload when only one plugin loaded", func() { - p1 := c.GetPlugins(false) - So(p1.Err, ShouldBeNil) - So(len(p1.LoadedPlugins), ShouldEqual, 1) - So(p1.LoadedPlugins[0].Name, ShouldEqual, "mock") - - p2 := c.UnloadPlugin("collector", "mock", 1) - So(p2.Err, ShouldBeNil) - So(p2.Name, ShouldEqual, "mock") - So(p2.Version, ShouldEqual, 1) - So(p2.Type, ShouldEqual, "collector") - - p3 := c.GetPlugins(false) - So(p3.Err, ShouldBeNil) - So(len(p3.LoadedPlugins), ShouldEqual, 0) + Convey("UnloadPlugin", func() { + Convey("unload unknown plugin", func() { + p := c.UnloadPlugin("not a type", "foo", 3) + So(p.Err, ShouldNotBeNil) + So(p.Err.Error(), ShouldEqual, "plugin not found") + }) + Convey("unload one of multiple", func() { + p1 := c.GetPlugins(false) + So(p1.Err, ShouldBeNil) + So(len(p1.LoadedPlugins), ShouldEqual, 3) + + p2 := c.UnloadPlugin("collector", "mock", 2) + So(p2.Err, ShouldBeNil) + So(p2.Name, ShouldEqual, "mock") + So(p2.Version, ShouldEqual, 2) + So(p2.Type, ShouldEqual, "collector") + + p3 := c.UnloadPlugin("publisher", "file", 3) + So(p3.Err, ShouldBeNil) + So(p3.Name, ShouldEqual, "file") + So(p3.Version, ShouldEqual, 3) + So(p3.Type, ShouldEqual, "publisher") + }) + Convey("unload when only one plugin loaded", func() { + p1 := c.GetPlugins(false) + So(p1.Err, ShouldBeNil) + So(len(p1.LoadedPlugins), ShouldEqual, 1) + So(p1.LoadedPlugins[0].Name, ShouldEqual, "mock") + + p2 := c.UnloadPlugin("collector", "mock", 1) + So(p2.Err, ShouldBeNil) + So(p2.Name, ShouldEqual, "mock") + So(p2.Version, ShouldEqual, 1) + So(p2.Type, ShouldEqual, "collector") + + p3 := c.GetPlugins(false) + So(p3.Err, ShouldBeNil) + So(len(p3.LoadedPlugins), ShouldEqual, 0) + }) }) }) - c = New("http://localhost:127.0.0.1:-1", "v1", true) - + c, err := New("http://localhost:127.0.0.1:-1", "v1", true) Convey("API with invalid port", t, func() { - p1 := c.LoadPlugin(MOCK_PLUGIN_PATH1) - So(p1.Err, ShouldNotBeNil) - So(p1.LoadedPlugins, ShouldBeEmpty) - - p2 := c.GetPlugins(false) - p3 := c.GetPlugins(true) - So(p2.Err, ShouldNotBeNil) - So(p3.Err, ShouldNotBeNil) + So(err, ShouldNotBeNil) + So(c, ShouldBeNil) + }) + + c, err = New("test", "", true) + Convey("API with invalid url - no scheme", t, func() { + So(err, ShouldNotBeNil) + So(c, ShouldBeNil) + }) + + c, err = New("ftp://127.0.0.1:1", "", true) + Convey("API with invalid url - ftp", t, func() { + So(err, ShouldNotBeNil) + So(c, ShouldBeNil) + }) + + c, err = New("htp://127.0.0.1:1 - typo", "", true) + Convey("API with invalid url", t, func() { + So(err, ShouldNotBeNil) + So(c, ShouldBeNil) }) } diff --git a/mgmt/rest/client/client_tribe_func_test.go b/mgmt/rest/client/client_tribe_func_test.go index 679e25d5b..6b41e083b 100644 --- a/mgmt/rest/client/client_tribe_func_test.go +++ b/mgmt/rest/client/client_tribe_func_test.go @@ -90,10 +90,12 @@ func getMembers(port int) *rbody.APIResponse { } func TestSnapClientTribe(t *testing.T) { + numOfTribes := 4 + ports := startTribes(numOfTribes) + c, err := client.New(fmt.Sprintf("http://localhost:%d", ports[0]), "v1", true) + Convey("REST API functional V1 - TRIBE", t, func() { - numOfTribes := 4 - ports := startTribes(numOfTribes) - c := client.New(fmt.Sprintf("http://localhost:%d", ports[0]), "v1", true) + So(err, ShouldBeNil) Convey("Get global membership", func() { resp := c.ListMembers() diff --git a/mgmt/tribe/worker/worker.go b/mgmt/tribe/worker/worker.go index 4c3b77ad8..53c10018e 100644 --- a/mgmt/tribe/worker/worker.go +++ b/mgmt/tribe/worker/worker.go @@ -385,7 +385,11 @@ func (w worker) createTask(taskID string, startOnCreate bool) { for _, member := range shuffle(members) { uri := fmt.Sprintf("%s://%s:%s", member.GetRestProto(), member.GetAddr(), member.GetRestPort()) logger.Debugf("getting task %v from %v", taskID, uri) - c := client.New(uri, "v1", member.GetRestInsecureSkipVerify()) + c, err := client.New(uri, "v1", member.GetRestInsecureSkipVerify()) + if err != nil { + logger.Error(err) + continue + } taskResult := c.GetTask(taskID) if taskResult.Err != nil { logger.WithField("err", taskResult.Err.Error()).Debug("error getting task")