func TestHANAPublish(t *testing.T) { var buf bytes.Buffer metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("test_string"), time.Now(), nil, "", "example_string"), *plugin.NewMetricType(core.NewNamespace("test_int"), time.Now(), nil, "", 1), *plugin.NewMetricType(core.NewNamespace("test_string_slice"), time.Now(), nil, "", []string{"str1", "str2"}), *plugin.NewMetricType(core.NewNamespace("test_string_slice"), time.Now(), nil, "", []int{1, 2}), *plugin.NewMetricType(core.NewNamespace("test_uint8"), time.Now(), nil, "", uint8(1)), } config := make(map[string]ctypes.ConfigValue) enc := gob.NewEncoder(&buf) enc.Encode(metrics) Convey("TestHANAPublish", t, func() { config["username"] = ctypes.ConfigValueStr{Value: "root"} config["password"] = ctypes.ConfigValueStr{Value: "root"} config["database"] = ctypes.ConfigValueStr{Value: "SNAP_TEST"} config["host"] = ctypes.ConfigValueStr{Value: "localhost"} config["port"] = ctypes.ConfigValueStr{Value: "1433"} config["tablename"] = ctypes.ConfigValueStr{Value: "info"} sp := NewHANAPublisher() cp, _ := sp.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) err := sp.Publish("", buf.Bytes(), *cfg) Convey("So not passing in a content type should result in an error", func() { So(err, ShouldResemble, errors.New("Unknown content type ''")) }) err = sp.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) Convey("So publishing metrics should not result in an error", func() { So(err, ShouldBeNil) }) }) }
// integration test func TestRiemannPublish(t *testing.T) { // This integration test requires a Riemann Server broker := os.Getenv("SNAP_TEST_RIEMANN") if broker == "" { fmt.Println("Skipping integration tests") return } var buf bytes.Buffer buf.Reset() r := NewRiemannPublisher() config := make(map[string]ctypes.ConfigValue) config["broker"] = ctypes.ConfigValueStr{Value: broker} cp, _ := r.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) tags := map[string]string{} tags[core.STD_TAG_PLUGIN_RUNNING_ON] = "bacon-powered" metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("intel", "cpu", "temp"), time.Now(), tags, "some unit", 100), } enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := r.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) Convey("Publish metric to Riemann", t, func() { Convey("So err should not be returned", func() { So(err, ShouldBeNil) }) Convey("So metric retrieved equals metric published", func() { c, _ := raidman.Dial("tcp", broker) events, _ := c.Query("host = \"bacon-powered\"") So(len(events), ShouldBeGreaterThan, 0) }) }) }
func TestHekaPublish(t *testing.T) { config := make(map[string]ctypes.ConfigValue) Convey("snap Plugin integration testing with Heka", t, func() { var buf bytes.Buffer buf.Reset() enc := gob.NewEncoder(&buf) config["host"] = ctypes.ConfigValueStr{Value: os.Getenv("SNAP_HEKA_HOST")} config["port"] = ctypes.ConfigValueInt{Value: 3242} op := NewHekaPublisher() cp, _ := op.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) Convey("Publish float metrics to Heka", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType( core.NewNamespace("intel", "psutil", "load", "load15"), time.Now(), nil, nil, 23.1), *plugin.NewMetricType( core.NewNamespace("intel", "psutil", "vm", "available"), time.Now().Add(2*time.Second), nil, nil, 23.2), *plugin.NewMetricType( core.NewNamespace("intel", "psutil", "load", " load1"), time.Now().Add(3*time.Second), nil, nil, 23.3), } enc.Encode(metrics) err := op.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish int metrics to Heka", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType( core.NewNamespace("intel", "psutil", "vm", "free"), time.Now().Add(5*time.Second), nil, nil, 88), } enc.Encode(metrics) err := op.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) }
func TestOpentsdbPublish(t *testing.T) { config := make(map[string]ctypes.ConfigValue) Convey("Snap Plugin integration testing with OpenTSDB", t, func() { var buf bytes.Buffer buf.Reset() enc := gob.NewEncoder(&buf) config["host"] = ctypes.ConfigValueStr{Value: os.Getenv("SNAP_OPENTSDB_HOST")} config["port"] = ctypes.ConfigValueInt{Value: 4242} op := NewOpentsdbPublisher() cp, _ := op.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) tags := map[string]string{} tags[core.STD_TAG_PLUGIN_RUNNING_ON] = "mac1" Convey("Publish float metrics to OpenTSDB", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("/psutil/load/load15"), time.Now(), tags, "float64", 23.1), *plugin.NewMetricType(core.NewNamespace("/psutil/vm/available"), time.Now().Add(2*time.Second), tags, "float64", 23.2), *plugin.NewMetricType(core.NewNamespace("/psutil/load/load1"), time.Now().Add(3*time.Second), tags, "float64", 23.3), } enc.Encode(metrics) err := op.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish int metrics to OpenTSDB", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("/psutil/vm/free"), time.Now().Add(5*time.Second), tags, "int", 23), } enc.Encode(metrics) err := op.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) }
func (m *mockCollectorProxy) CollectMetrics(args []byte, reply *[]byte) error { rand.Seed(time.Now().Unix()) var dargs plugin.CollectMetricsArgs err := m.e.Decode(args, &dargs) if err != nil { return err } var mts []plugin.MetricType for _, i := range dargs.MetricTypes { p := plugin.NewMetricType(i.Namespace(), time.Now(), nil, "", rand.Intn(100)) p.Config_ = i.Config() mts = append(mts, *p) } cmr := &plugin.CollectMetricsReply{PluginMetrics: mts} *reply, err = m.e.Encode(cmr) if err != nil { return err } return nil }
// createMetricsSubArray creates an array of metrics for map values returned by facter func createMetricsSubArray(name string, value map[string]interface{}) ([]plugin.MetricType, error) { var ms []plugin.MetricType namespaces := []string{} err := utils.FromMap(value, name, &namespaces) if err != nil { return nil, err } for _, namespace := range namespaces { ns := strings.Split(namespace, "/") val := utils.GetValueByNamespace(value, ns[1:]) m := *plugin.NewMetricType(createNamespace(ns...), time.Now(), nil, "", val) ms = append(ms, m) } return ms, nil }
// parseFacts parses facts returned by facter and extracts metricTypes from it func parseFacts(f facts) ([]plugin.MetricType, error) { var metricTypes []plugin.MetricType // create types with given namespace for name, value := range f { if val, ok := value.(map[string]interface{}); ok { ms, err := createMetricsSubArray(name, val) if err != nil { return nil, err } metricTypes = append(metricTypes, ms...) } else { metricType := *plugin.NewMetricType(createNamespace(name), time.Now(), nil, "", value) metricTypes = append(metricTypes, metricType) } } return metricTypes, nil }
func TestMySQLPublish(t *testing.T) { var buf bytes.Buffer tags := map[string]string{} tags[core.STD_TAG_PLUGIN_RUNNING_ON] = "127.0.0.1" metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("test", "string"), time.Now(), tags, "", "example_string"), *plugin.NewMetricType(core.NewNamespace("test", "int"), time.Now(), tags, "", 1), *plugin.NewMetricType(core.NewNamespace("test", "string", "slice"), time.Now(), tags, "", []string{"str1", "str2"}), *plugin.NewMetricType(core.NewNamespace("test", "string", "slice"), time.Now(), tags, "", []int{1, 2}), *plugin.NewMetricType(core.NewNamespace("test", "uint"), time.Now(), tags, "", uint(1)), *plugin.NewMetricType(core.NewNamespace("test", "uint", "slice"), time.Now(), tags, "", []uint{uint(1), uint(2)}), } enc := gob.NewEncoder(&buf) enc.Encode(metrics) Convey("Publish data to existing database", t, func() { config := make(map[string]ctypes.ConfigValue) config["username"] = ctypes.ConfigValueStr{Value: "root"} config["password"] = ctypes.ConfigValueStr{Value: ""} config["database"] = ctypes.ConfigValueStr{Value: "snap_test"} config["tablename"] = ctypes.ConfigValueStr{Value: "info"} mp := NewMySQLPublisher() cp, _ := mp.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) Convey("Publish metrics to MySQL instance should succeed and not throw an error", func() { err := mp.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) Convey("Publish data to non-existing database", t, func() { config := make(map[string]ctypes.ConfigValue) config["username"] = ctypes.ConfigValueStr{Value: "root"} config["password"] = ctypes.ConfigValueStr{Value: ""} config["database"] = ctypes.ConfigValueStr{Value: "snap_test1"} config["tablename"] = ctypes.ConfigValueStr{Value: "info"} mp := NewMySQLPublisher() cp, _ := mp.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) Convey("Publish metrics to MySQL instance should succeed and not throw an error", func() { err := mp.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) }
func TestFilePublish(t *testing.T) { var buf bytes.Buffer metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", 99), } config := make(map[string]ctypes.ConfigValue) enc := gob.NewEncoder(&buf) enc.Encode(metrics) Convey("TestFilePublish", t, func() { config["file"] = ctypes.ConfigValueStr{Value: "/tmp/pub.out"} fp := NewFilePublisher() So(fp, ShouldNotBeNil) err := fp.Publish("", buf.Bytes(), config) So(err, ShouldResemble, errors.New("Unknown content type ''")) err = fp.Publish(plugin.SnapGOBContentType, buf.Bytes(), config) So(err, ShouldBeNil) _, err = os.Stat(config["file"].(ctypes.ConfigValueStr).Value) So(err, ShouldBeNil) meta := Meta() So(meta, ShouldNotBeNil) }) }
package kafka import ( "testing" "time" "github.com/intelsdi-x/snap/control/plugin" "github.com/intelsdi-x/snap/control/plugin/cpolicy" "github.com/intelsdi-x/snap/core" "github.com/intelsdi-x/snap/core/ctypes" . "github.com/smartystreets/goconvey/convey" ) var mockMts = []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", 99), } func TestMetaData(t *testing.T) { Convey("Meta returns proper metadata", t, func() { meta := Meta() So(meta, ShouldNotBeNil) So(meta.Name, ShouldResemble, PluginName) So(meta.Version, ShouldResemble, PluginVersion) So(meta.Type, ShouldResemble, PluginType) }) } func TestKafkaPlugin(t *testing.T) { Convey("Create Kafka Publisher", t, func() { k := NewKafkaPublisher()
func TestHTTPJSONRPC(t *testing.T) { log.SetLevel(log.DebugLevel) addr, session := startHTTPJSONRPC() time.Sleep(time.Millisecond * 100) Convey("Collector Client", t, func() { session.c = true c, err := NewCollectorHttpJSONRPCClient(fmt.Sprintf("http://%v", addr), 1*time.Second, &key.PublicKey, true) So(err, ShouldBeNil) So(c, ShouldNotBeNil) cl := c.(*httpJSONRPCClient) cl.encrypter.Key = symkey Convey("Ping", func() { err := c.Ping() So(err, ShouldBeNil) }) Convey("Kill", func() { err := c.Kill("somereason") So(err, ShouldBeNil) }) Convey("GetMetricTypes", func() { cfg := plugin.NewPluginConfigType() cfg.AddItem("test", ctypes.ConfigValueBool{Value: true}) mts, err := c.GetMetricTypes(cfg) So(err, ShouldBeNil) So(mts, ShouldNotBeNil) So(mts, ShouldHaveSameTypeAs, []core.Metric{}) So(len(mts), ShouldBeGreaterThan, 0) So(len(mts[0].Config().Table()), ShouldBeGreaterThan, 0) }) Convey("CollectMetrics provided a valid config", func() { cdn := cdata.NewNode() cdn.AddItem("someInt", ctypes.ConfigValueInt{Value: 1}) cdn.AddItem("password", ctypes.ConfigValueStr{Value: "secure"}) time.Sleep(500 * time.Millisecond) mts, err := c.CollectMetrics([]core.Metric{ &plugin.MetricType{ Namespace_: core.NewNamespace("foo", "bar"), Config_: cdn, }, }) So(err, ShouldBeNil) So(mts, ShouldNotBeNil) So(mts, ShouldHaveSameTypeAs, []core.Metric{}) So(len(mts), ShouldBeGreaterThan, 0) So(mts[0].Config().Table(), ShouldNotBeEmpty) So(mts[0].Config().Table()["someInt"].Type(), ShouldResemble, "integer") Convey("Get and process the ConfigPolicy", func() { cp, err := c.GetConfigPolicy() So(err, ShouldBeNil) So(cp, ShouldNotBeNil) So(cp.Get([]string{"foo", "bar"}), ShouldNotBeNil) node := cp.Get([]string{"foo", "bar"}) So(node, ShouldNotBeNil) cpn, cserrs := node.Process(mts[0].Config().Table()) So(cpn, ShouldNotBeNil) So((*cpn)["somefloat"].Type(), ShouldResemble, "float") So((*cpn)["somefloat"].(ctypes.ConfigValueFloat).Value, ShouldResemble, 3.14) So(cserrs.Errors(), ShouldBeEmpty) }) }) Convey("CollectMetrics provided an invalid config", func() { cdn := cdata.NewNode() cdn.AddItem("someInt", ctypes.ConfigValueInt{Value: 1}) time.Sleep(500 * time.Millisecond) mts, err := c.CollectMetrics([]core.Metric{ &plugin.MetricType{ Namespace_: core.NewNamespace("foo", "bar"), Config_: cdn, }, }) So(err, ShouldBeNil) So(mts, ShouldNotBeNil) So(mts, ShouldHaveSameTypeAs, []core.Metric{}) So(len(mts), ShouldBeGreaterThan, 0) So(mts[0].Config().Table(), ShouldNotBeEmpty) So(mts[0].Config().Table()["someInt"].Type(), ShouldResemble, "integer") Convey("Get and process the ConfigPolicy", func() { cp, err := c.GetConfigPolicy() So(err, ShouldBeNil) So(cp, ShouldNotBeNil) node := cp.Get([]string{"foo", "bar"}) So(node, ShouldNotBeNil) So(err, ShouldBeNil) _, cserrs := node.Process(mts[0].Config().Table()) //So(cpn, ShouldBeNil) So(cserrs.Errors(), ShouldNotBeEmpty) So(len(cserrs.Errors()), ShouldEqual, 1) So(cserrs.Errors()[0].Error(), ShouldContainSubstring, "password") }) }) }) Convey("Processor Client", t, func() { session.c = false p, _ := NewProcessorHttpJSONRPCClient(fmt.Sprintf("http://%v", addr), 1*time.Second, &key.PublicKey, true) cl := p.(*httpJSONRPCClient) cl.encrypter.Key = symkey So(p, ShouldNotBeNil) Convey("GetConfigPolicy", func() { cp, err := p.GetConfigPolicy() So(err, ShouldBeNil) So(cp, ShouldNotBeNil) cp_ := cpolicy.New() cpn_ := cpolicy.NewPolicyNode() r1, err := cpolicy.NewIntegerRule("SomeRequiredInt", true, 1) r2, _ := cpolicy.NewStringRule("password", true) r3, _ := cpolicy.NewFloatRule("somefloat", false, 3.14) So(err, ShouldBeNil) cpn_.Add(r1, r2, r3) cp_.Add([]string{""}, cpn_) cpjson, _ := cp.MarshalJSON() cp_json, _ := cp_.MarshalJSON() So(string(cpjson), ShouldResemble, string(cp_json)) }) Convey("Process metrics", func() { pmt := plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "", 1) b, _ := json.Marshal([]plugin.MetricType{*pmt}) contentType, content, err := p.Process(plugin.SnapJSONContentType, b, nil) So(contentType, ShouldResemble, plugin.SnapJSONContentType) So(content, ShouldNotBeNil) So(err, ShouldEqual, nil) var pmts []plugin.MetricType err = json.Unmarshal(content, &pmts) So(err, ShouldBeNil) So(len(pmts), ShouldEqual, 1) So(pmts[0].Data(), ShouldEqual, 1) So(pmts[0].Namespace(), ShouldResemble, core.NewNamespace("foo", "bar")) }) }) Convey("Publisher Client", t, func() { session.c = false p, _ := NewPublisherHttpJSONRPCClient(fmt.Sprintf("http://%v", addr), 1*time.Second, &key.PublicKey, true) cl := p.(*httpJSONRPCClient) cl.encrypter.Key = symkey So(p, ShouldNotBeNil) Convey("GetConfigPolicy", func() { cp, err := p.GetConfigPolicy() So(err, ShouldBeNil) So(cp, ShouldNotBeNil) cp_ := cpolicy.New() cpn_ := cpolicy.NewPolicyNode() r1, err := cpolicy.NewIntegerRule("SomeRequiredInt", true, 1) r2, _ := cpolicy.NewStringRule("password", true) r3, _ := cpolicy.NewFloatRule("somefloat", false, 3.14) So(err, ShouldBeNil) cpn_.Add(r1, r2, r3) cp_.Add([]string{""}, cpn_) cpjson, _ := cp.MarshalJSON() cp_json, _ := cp_.MarshalJSON() So(string(cpjson), ShouldResemble, string(cp_json)) }) Convey("Publish metrics", func() { pmt := plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "", 1) b, _ := json.Marshal([]plugin.MetricType{*pmt}) err := p.Publish(plugin.SnapJSONContentType, b, nil) So(err, ShouldBeNil) }) }) }
func TestHekaPlugin(t *testing.T) { Convey("Meta should return metadata for the plugin", t, func() { meta := Meta() So(meta.Name, ShouldResemble, pluginName) So(meta.Version, ShouldResemble, version) So(meta.Type, ShouldResemble, plugin.PublisherPluginType) }) Convey("Create HekaPublisher", t, func() { op := NewHekaPublisher() Convey("So heka publisher should not be nil", func() { So(op, ShouldNotBeNil) }) Convey("So heka publisher should be of heka type", func() { So(op, ShouldHaveSameTypeAs, &hekaPublisher{}) }) Convey("op.GetConfigPolicy() should return a config policy", func() { configPolicy, _ := op.GetConfigPolicy() Convey("So config policy should not be nil", func() { So(configPolicy, ShouldNotBeNil) }) Convey("So config policy should be a cpolicy.ConfigPolicy", func() { So(configPolicy, ShouldHaveSameTypeAs, &cpolicy.ConfigPolicy{}) }) testConfig := make(map[string]ctypes.ConfigValue) testConfig["host"] = ctypes.ConfigValueStr{Value: "localhost"} testConfig["port"] = ctypes.ConfigValueInt{Value: 6565} cfg, errs := configPolicy.Get([]string{vendor, pluginName}).Process(testConfig) Convey("So config policy should process testConfig and return a config", func() { So(cfg, ShouldNotBeNil) }) Convey("So testConfig processing should return no errors", func() { So(errs.HasErrors(), ShouldBeFalse) }) testConfig["port"] = ctypes.ConfigValueStr{Value: "6565"} cfg, errs = configPolicy.Get([]string{vendor, pluginName}).Process(testConfig) Convey("So config policy should not return a config after processing invalid testConfig", func() { So(cfg, ShouldBeNil) }) Convey("So testConfig processing should return errors", func() { So(errs.HasErrors(), ShouldBeTrue) }) }) }) Convey("Create SnapHekaClient", t, func() { Convey("The SnapHekaClient should not be nil", func() { client, _ := NewSnapHekaClient("tcp://localhost:5600", "") So(client, ShouldNotBeNil) }) Convey("Testing createHekaMessage", func() { var dynElt, staElt core.NamespaceElement tags := map[string]string{"tag_key": "tag_val"} // namespace is foo.<bar>.<name>.baz namespace := core.NewNamespace("foo") dynElt = core.NamespaceElement{ Name: "bar", Description: "", Value: "bar_val"} namespace = append(namespace, dynElt) dynElt = core.NamespaceElement{ Name: "name", Description: "", Value: "name_val"} namespace = append(namespace, dynElt) staElt = core.NamespaceElement{ Name: "", Description: "", Value: "baz"} namespace = append(namespace, staElt) metric := *plugin.NewMetricType(namespace, time.Now(), tags, "some unit", 3.141) message, _ := createHekaMessage("some payload", metric, 1234, "host0") Convey("The Heka message should not be nil", func() { So(message, ShouldNotBeNil) }) Convey("The Heka message should be as expected", func() { So(message.GetHostname(), ShouldEqual, "host0") So(message.GetLogger(), ShouldEqual, "snap.heka.logger") So(message.GetPayload(), ShouldEqual, "some payload") So(message.GetPid(), ShouldEqual, 1234) So(message.GetSeverity(), ShouldEqual, 6) So(message.GetType(), ShouldEqual, "snap.heka") fields := message.GetFields() So(fields, ShouldNotBeNil) So(fields[0].GetName(), ShouldEqual, "bar") So(fields[0].GetValue(), ShouldEqual, "bar_val") So(fields[1].GetName(), ShouldEqual, "name") So(fields[1].GetValue(), ShouldEqual, "name_val") So(fields[2].GetName(), ShouldEqual, "tag_key") So(fields[2].GetValue(), ShouldEqual, "tag_val") So(fields[3].GetName(), ShouldEqual, "dimensions") So(fields[3].GetValueString(), ShouldResemble, []string{"bar", "name", "tag_key"}) So(fields[4].GetName(), ShouldEqual, "name") So(fields[4].GetValue(), ShouldEqual, "foo.baz") So(fields[5].GetName(), ShouldEqual, "value") So(fields[5].GetValue(), ShouldEqual, 3.141) So(fields[6].GetName(), ShouldEqual, "timestamp") }) }) }) }
func TestInfluxPublish(t *testing.T) { config := make(map[string]ctypes.ConfigValue) Convey("snap plugin InfluxDB integration testing with Influx", t, func() { var buf bytes.Buffer var retention string if strings.HasPrefix(os.Getenv("INFLUXDB_VERSION"), "0.") { retention = "default" } else { retention = "autogen" } config["host"] = ctypes.ConfigValueStr{Value: os.Getenv("SNAP_INFLUXDB_HOST")} config["port"] = ctypes.ConfigValueInt{Value: 8086} config["https"] = ctypes.ConfigValueBool{Value: false} config["skip-verify"] = ctypes.ConfigValueBool{Value: false} config["user"] = ctypes.ConfigValueStr{Value: "root"} config["password"] = ctypes.ConfigValueStr{Value: "root"} config["database"] = ctypes.ConfigValueStr{Value: "test"} config["retention"] = ctypes.ConfigValueStr{Value: retention} config["debug"] = ctypes.ConfigValueBool{Value: false} config["log-level"] = ctypes.ConfigValueStr{Value: "debug"} ip := NewInfluxPublisher() cp, _ := ip.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) tags := map[string]string{"zone": "red"} Convey("Publish integer metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), tags, "some unit", 99), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish float metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("bar"), time.Now(), tags, "some unit", 3.141), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish string metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("qux"), time.Now(), tags, "some unit", "bar"), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish boolean metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("baz"), time.Now(), tags, "some unit", true), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish multiple metrics", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), tags, "some unit", 101), *plugin.NewMetricType(core.NewNamespace("bar"), time.Now(), tags, "some unit", 5.789), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish dynamic metrics", func() { dynamicNS1 := core.NewNamespace("foo"). AddDynamicElement("dynamic", "dynamic elem"). AddStaticElement("bar") dynamicNS2 := core.NewNamespace("foo"). AddDynamicElement("dynamic_one", "dynamic element one"). AddDynamicElement("dynamic_two", "dynamic element two"). AddStaticElement("baz") dynamicNS1[1].Value = "fooval" dynamicNS2[1].Value = "barval" dynamicNS2[2].Value = "bazval" metrics := []plugin.MetricType{ *plugin.NewMetricType(dynamicNS1, time.Now(), tags, "", 123), *plugin.NewMetricType(dynamicNS2, time.Now(), tags, "", 456), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish nil value of metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("baz"), time.Now(), tags, "some unit", nil), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) }
func TestPostgresPublish(t *testing.T) { config := make(map[string]ctypes.ConfigValue) Convey("Snap Plugin PostgreSQL integration testing with PostgreSQL", t, func() { var buf bytes.Buffer config["hostname"] = ctypes.ConfigValueStr{Value: os.Getenv("SNAP_POSTGRESQL_HOST")} config["port"] = ctypes.ConfigValueInt{Value: 5432} config["username"] = ctypes.ConfigValueStr{Value: "postgres"} config["password"] = ctypes.ConfigValueStr{Value: ""} config["database"] = ctypes.ConfigValueStr{Value: "snap_test"} config["table_name"] = ctypes.ConfigValueStr{Value: "info"} ip := NewPostgreSQLPublisher() cp, _ := ip.GetConfigPolicy() cfg, _ := cp.Get([]string{""}).Process(config) Convey("Publish integer metric (int)", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", 99), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish integer metric (int64)", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", int64(99)), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish unsigned integer metric (uint)", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", uint(99)), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish unsigned integer metric (uint64)", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", uint64(99)), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish float metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("bar"), time.Now(), nil, "", 3.141), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish string metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("qux"), time.Now(), nil, "", "bar"), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish boolean metric", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("baz"), time.Now(), nil, "", true), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) Convey("Publish multiple metrics", func() { metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("foo"), time.Now(), nil, "", 101), *plugin.NewMetricType(core.NewNamespace("bar"), time.Now(), nil, "", 5.789), } buf.Reset() enc := gob.NewEncoder(&buf) enc.Encode(metrics) err := ip.Publish(plugin.SnapGOBContentType, buf.Bytes(), *cfg) So(err, ShouldBeNil) }) }) }
func (m *Mesos) CollectMetrics(mts []plugin.MetricType) ([]plugin.MetricType, error) { configItems, err := getConfig(mts[0]) if err != nil { return nil, err } requestedMaster := []core.Namespace{} requestedAgent := []core.Namespace{} for _, metricType := range mts { switch metricType.Namespace().Strings()[2] { case "master": requestedMaster = append(requestedMaster, metricType.Namespace()) case "agent": requestedAgent = append(requestedAgent, metricType.Namespace()) } } // Translate Mesos metrics into Snap PluginMetrics now := time.Now() metrics := []plugin.MetricType{} if configItems["master"] != "" && len(requestedMaster) > 0 { log.Info("Collecting ", len(requestedMaster), " metrics from the master") isLeader, err := master.IsLeader(configItems["master"]) if err != nil { log.Error(err) return nil, err } if isLeader { snapshot, err := master.GetMetricsSnapshot(configItems["master"]) if err != nil { log.Error(err) return nil, err } frameworks, err := master.GetFrameworks(configItems["master"]) if err != nil { log.Error(err) return nil, err } tags := map[string]string{"source": configItems["master"]} for _, requested := range requestedMaster { isDynamic, _ := requested.IsDynamic() if isDynamic { n := requested.Strings()[4:] // Iterate through the array of frameworks returned by GetFrameworks() for _, framework := range frameworks { val := ns.GetValueByNamespace(framework, n) if val == nil { log.Warn("Attempted to collect metric ", requested.String(), " but it returned nil!") continue } // substituting "framework" wildcard with particular framework id requested[3].Value = framework.ID // TODO(roger): units metrics = append(metrics, *plugin.NewMetricType(requested, now, tags, "", val)) } } else { n := requested.Strings()[3:] val, ok := snapshot[strings.Join(n, "/")] if !ok { e := fmt.Errorf("error: requested metric %s not found", requested.String()) log.Error(e) return nil, e } //TODO(kromar): is it possible to provide unit NewMetricType(ns, time, tags, unit, value)? // I'm leaving empty string for now... metrics = append(metrics, *plugin.NewMetricType(requested, now, tags, "", val)) } } } else { log.Info("Attempted CollectMetrics() on ", configItems["master"], "but it isn't the leader. Skipping...") } } if configItems["agent"] != "" && len(requestedAgent) > 0 { log.Info("Collecting ", len(requestedAgent), " metrics from the agent") snapshot, err := agent.GetMetricsSnapshot(configItems["agent"]) if err != nil { log.Error(err) return nil, err } executors, err := agent.GetMonitoringStatistics(configItems["agent"]) if err != nil { log.Error(err) return nil, err } tags := map[string]string{"source": configItems["agent"]} for _, requested := range requestedAgent { n := requested.Strings()[5:] isDynamic, _ := requested.IsDynamic() if isDynamic { // Iterate through the array of executors returned by GetMonitoringStatistics() for _, exec := range executors { val := ns.GetValueByNamespace(exec.Statistics, n) if val == nil { log.Warn("Attempted to collect metric ", requested.String(), " but it returned nil!") continue } // substituting "framework" wildcard with particular framework id requested[3].Value = exec.Framework // substituting "executor" wildcard with particular executor id requested[4].Value = exec.ID // TODO(roger): units metrics = append(metrics, *plugin.NewMetricType(requested, now, tags, "", val)) } } else { // Get requested metrics from the snapshot map n := requested.Strings()[3:] val, ok := snapshot[strings.Join(n, "/")] if !ok { e := fmt.Errorf("error: requested metric %v not found", requested.String()) log.Error(e) return nil, e } //TODO(kromar): units here also? metrics = append(metrics, *plugin.NewMetricType(requested, now, tags, "", val)) } } } log.Debug("Collected a total of ", len(metrics), " metrics.") return metrics, nil }
func TestPostgreSQLPublish(t *testing.T) { var buf bytes.Buffer //mock.ExpectBegin() expTime := time.Now() metrics := []plugin.MetricType{ *plugin.NewMetricType(core.NewNamespace("test_string"), expTime, nil, "", "example_string"), *plugin.NewMetricType(core.NewNamespace("test_int"), expTime, nil, "", int(-1)), *plugin.NewMetricType(core.NewNamespace("test_int64"), expTime, nil, "", int64(1)), *plugin.NewMetricType(core.NewNamespace("test_uint"), expTime, nil, "", uint(1)), *plugin.NewMetricType(core.NewNamespace("test_uint64"), expTime, nil, "", uint64(1)), *plugin.NewMetricType(core.NewNamespace("test_float"), expTime, nil, "", 1.12), *plugin.NewMetricType(core.NewNamespace("test_float64"), expTime, nil, "", float64(-1.23)), *plugin.NewMetricType(core.NewNamespace("test_bool"), expTime, nil, "", true), *plugin.NewMetricType(core.NewNamespace("test_string_slice"), expTime, nil, "", []string{"str1", "str2"}), *plugin.NewMetricType(core.NewNamespace("test_int_slice"), expTime, nil, "", []int{-1, 2}), *plugin.NewMetricType(core.NewNamespace("test_int64_slice"), expTime, nil, "", []int64{-1, 2}), *plugin.NewMetricType(core.NewNamespace("test_uint_slice"), expTime, nil, "", []uint{1, 2}), *plugin.NewMetricType(core.NewNamespace("test_uint64_slice"), expTime, nil, "", []uint64{1, 2}), *plugin.NewMetricType(core.NewNamespace("test_float64_slice"), expTime, nil, "", []float64{1.23, -1.23}), } config := make(map[string]ctypes.ConfigValue) enc := gob.NewEncoder(&buf) enc.Encode(metrics) Convey("TestPostgreSQLPublish", t, func() { config["hostname"] = ctypes.ConfigValueStr{Value: "localhost"} config["port"] = ctypes.ConfigValueInt{Value: 5432} config["username"] = ctypes.ConfigValueStr{Value: "postgres"} config["password"] = ctypes.ConfigValueStr{Value: ""} config["database"] = ctypes.ConfigValueStr{Value: "snap_test"} config["table_name"] = ctypes.ConfigValueStr{Value: "info"} sp := NewPostgreSQLPublisher() So(sp, ShouldNotBeNil) err := sp.Publish("", buf.Bytes(), config) So(err, ShouldResemble, errors.New("Unknown content type ''")) err = sp.Publish(plugin.SnapGOBContentType, buf.Bytes(), config) meta := Meta() So(meta, ShouldNotBeNil) }) }
func TestMovingAverageProcessorMetrics(t *testing.T) { Convey("Moving Average Processor tests", t, func() { metrics := make([]plugin.MetricType, 10) config := make(map[string]ctypes.ConfigValue) config["MovingAvgBufLength"] = ctypes.ConfigValueInt{Value: -1} Convey("Moving average for int data", func() { for i := range metrics { time.Sleep(3) rand.Seed(time.Now().UTC().UnixNano()) data := randInt(65, 90) metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", data) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), config) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) Convey("Moving average for float32 data", func() { config["MovingAvgBufLength"] = ctypes.ConfigValueInt{Value: 40} for i := range metrics { time.Sleep(3) rand.Seed(time.Now().UTC().UnixNano()) data := randInt(65, 90) metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", float32(data)) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), config) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) Convey("Moving average for float64 data", func() { for i := range metrics { time.Sleep(3) rand.Seed(time.Now().UTC().UnixNano()) data := randInt(65, 90) metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", float64(data)) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), nil) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) Convey("Moving average for uint32 data", func() { for i := range metrics { time.Sleep(3) rand.Seed(time.Now().UTC().UnixNano()) data := randInt(65, 90) metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", uint32(data)) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), nil) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) Convey("Moving average for uint64 data", func() { for i := range metrics { time.Sleep(3) rand.Seed(time.Now().UTC().UnixNano()) data := randInt(65, 90) metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", uint64(data)) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), nil) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) Convey("Moving average for unknown data type", func() { for i := range metrics { data := "I am an unknow data Type" metrics[i] = *plugin.NewMetricType(core.NewNamespace("foo", "bar"), time.Now(), nil, "some unit", data) } var buf bytes.Buffer enc := gob.NewEncoder(&buf) enc.Encode(metrics) movingAverageObj := NewMovingaverageProcessor() _, receivedData, _ := movingAverageObj.Process("snap.gob", buf.Bytes(), nil) var metricsNew []plugin.MetricType //Decodes the content into MetricType dec := gob.NewDecoder(bytes.NewBuffer(receivedData)) dec.Decode(&metricsNew) So(metrics, ShouldNotResemble, metricsNew) }) }) }
// This test is meant to cover the grpc implementation of the subset of control // features that scheduler uses. It is not intended to test the control features // themselves, only that we are correctly passing data over grpc and correctly // passing success/errors. func TestGRPCServerScheduler(t *testing.T) { l, _ := net.Listen("tcp", ":0") l.Close() cfg := GetDefaultConfig() cfg.ListenPort = l.Addr().(*net.TCPAddr).Port c := New(cfg) err := c.Start() Convey("Starting control_proxy server/client", t, func() { Convey("So err should be nil", func() { So(err, ShouldBeNil) }) }) // Load 3 plugins // collector -- mock // processor -- passthru // publisher -- file mock, err := core.NewRequestedPlugin(fixtures.JSONRPCPluginPath) if err != nil { log.Fatal(err) } c.Load(mock) passthru, err := core.NewRequestedPlugin(path.Join(fixtures.SnapPath, "plugin", "snap-processor-passthru")) if err != nil { log.Fatal(err) } c.Load(passthru) filepub, err := core.NewRequestedPlugin(path.Join(fixtures.SnapPath, "plugin", "snap-publisher-file")) if err != nil { log.Fatal(err) } c.Load(filepub) conn, err := rpcutil.GetClientConnection(c.Config.ListenAddr, c.Config.ListenPort) Convey("Creating an rpc connection", t, func() { Convey("Should not error", func() { So(err, ShouldBeNil) }) }) client := rpc.NewMetricManagerClient(conn) Convey("Creating an RPC client to control RPC server", t, func() { Convey("And a client should exist", func() { So(client, ShouldNotBeNil) }) }) //GetContentTypes Convey("Getting Content Types", t, func() { Convey("Should err if invalid plugin given", func() { req := &rpc.GetPluginContentTypesRequest{ Name: "bogus", PluginType: int32(0), Version: int32(0), } reply, err := client.GetPluginContentTypes(context.Background(), req) // We don't expect rpc errors So(err, ShouldBeNil) So(reply.Error, ShouldNotEqual, "") So(reply.Error, ShouldResemble, "plugin not found") }) Convey("Should return content types with valid plugin", func() { req := &rpc.GetPluginContentTypesRequest{ Name: "mock", PluginType: int32(0), Version: 0, } reply, err := client.GetPluginContentTypes(context.Background(), req) So(err, ShouldBeNil) So(reply.Error, ShouldEqual, "") So(reply.AcceptedTypes, ShouldContain, "snap.gob") So(reply.ReturnedTypes, ShouldContain, "snap.gob") }) }) // Verify that validate deps is properly passing through errors Convey("Validating Deps", t, func() { Convey("Should Fail if given invalid info", func() { req := &rpc.ValidateDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.InvalidMetric}), Plugins: common.ToSubPluginsMsg([]core.SubscribedPlugin{}), } reply, err := client.ValidateDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) }) Convey("with valid metrics", func() { req := &rpc.ValidateDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.ValidMetric}), Plugins: common.ToSubPluginsMsg([]core.SubscribedPlugin{}), } reply, err := client.ValidateDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) }) }) //Subscribe Deps: valid/invalid Convey("SubscribeDeps", t, func() { Convey("Should Error with invalid inputs", func() { req := &rpc.SubscribeDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.InvalidMetric}), Plugins: common.ToCorePluginsMsg([]core.Plugin{}), TaskId: "my-snowflake-id", } reply, err := client.SubscribeDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) So(reply.Errors[0].ErrorString, ShouldResemble, "Metric not found: /this/is/invalid") }) Convey("Should not error with valid inputs", func() { req := &rpc.SubscribeDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.ValidMetric}), Plugins: common.ToCorePluginsMsg([]core.Plugin{}), TaskId: "my-snowflake-id", } reply, err := client.SubscribeDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldEqual, 0) }) }) // unsubscribedeps -- valid/invalid Convey("UnsubscribeDeps", t, func() { Convey("Should Error with invalid inputs", func() { req := &rpc.SubscribeDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.InvalidMetric}), Plugins: common.ToCorePluginsMsg([]core.Plugin{}), TaskId: "my-snowflake-id", } reply, err := client.UnsubscribeDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) So(reply.Errors[0].ErrorString, ShouldResemble, "Metric not found: /this/is/invalid") }) Convey("Should not error with valid inputs", func() { req := &rpc.SubscribeDepsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.ValidMetric}), Plugins: common.ToCorePluginsMsg([]core.Plugin{}), TaskId: "my-snowflake-id", } reply, err := client.UnsubscribeDeps(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldEqual, 0) }) }) //matchquerytonamespaces -- valid/invalid Convey("MatchingQueryToNamespaces", t, func() { Convey("Should error with invalid inputs", func() { req := &rpc.ExpandWildcardsRequest{ Namespace: common.ToNamespace(fixtures.InvalidMetric.Namespace()), } reply, err := client.MatchQueryToNamespaces(context.Background(), req) // we don't expect rpc.errors So(err, ShouldBeNil) So(reply.Error, ShouldNotBeNil) So(reply.Error.ErrorString, ShouldResemble, "Metric not found: /this/is/invalid") }) Convey("Should not error with invalid inputs", func() { req := &rpc.ExpandWildcardsRequest{ Namespace: common.ToNamespace(fixtures.ValidMetric.Namespace()), } reply, err := client.MatchQueryToNamespaces(context.Background(), req) // we don't expect rpc.errors So(err, ShouldBeNil) So(reply.Error, ShouldBeNil) }) }) //expandwildcards -- valid/invalid Convey("ExpandWildcards", t, func() { Convey("Should error with invalid inputs", func() { req := &rpc.ExpandWildcardsRequest{ Namespace: common.ToNamespace(fixtures.InvalidMetric.Namespace()), } reply, err := client.ExpandWildcards(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(reply.Error, ShouldNotBeNil) So(reply.Error.ErrorString, ShouldResemble, "Metric not found: /this/is/invalid") }) Convey("Should not error with valid inputs", func() { req := &rpc.ExpandWildcardsRequest{ Namespace: common.ToNamespace(fixtures.ValidMetric.Namespace()), } reply, err := client.ExpandWildcards(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(reply.Error, ShouldBeNil) }) }) // start plugin pools/provide task info so we can do collect/process/publishMetrics // errors here indicate problems outside the scope of this test. plugins := []string{"collector:mock:1", "processor:passthru:1", "publisher:file:3"} lps := make([]*loadedPlugin, len(plugins)) pools := make([]strategy.Pool, len(plugins)) for i, v := range plugins { lps[i], err = c.pluginManager.get(v) if err != nil { log.Fatal(err) } pools[i], err = c.pluginRunner.AvailablePlugins().getOrCreatePool(v) if err != nil { log.Fatal(err) } pools[i].Subscribe("my-snowflake-id", strategy.BoundSubscriptionType) err = c.pluginRunner.runPlugin(lps[i].Details) if err != nil { log.Fatal(err) } } //our returned metrics var mts []core.Metric //collect Convey("CollectMetrics", t, func() { Convey("Should error with invalid inputs", func() { req := &rpc.CollectMetricsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.InvalidMetric}), Deadline: &common.Time{ Sec: int64(time.Now().Unix()), Nsec: int64(time.Now().Nanosecond()), }, TaskID: "my-snowflake-id", } reply, err := client.CollectMetrics(context.Background(), req) So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) }) Convey("should not error with valid inputs", func() { req := &rpc.CollectMetricsRequest{ Metrics: common.NewMetrics([]core.Metric{fixtures.ValidMetric}), Deadline: &common.Time{ Sec: int64(time.Now().Unix()), Nsec: int64(time.Now().Nanosecond()), }, TaskID: "my-snowflake-id", } reply, err := client.CollectMetrics(context.Background(), req) So(err, ShouldBeNil) So(len(reply.Errors), ShouldEqual, 0) So(reply.Metrics[0].Namespace, ShouldResemble, common.ToNamespace(fixtures.ValidMetric.Namespace())) // Used in a later test as metrics to be passed to processor mts = common.ToCoreMetrics(reply.Metrics) }) }) //our content to pass to publish var content []byte //process Convey("ProcessMetrics", t, func() { Convey("Should error with invalid inputs", func() { req := controlproxy.GetPubProcReq("snap.gob", []byte{}, "bad name", 1, map[string]ctypes.ConfigValue{}, "my-snowflake-id") reply, err := client.ProcessMetrics(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) So(reply.Errors[0], ShouldResemble, "bad key") }) Convey("should not error with valid inputs", func() { var buf bytes.Buffer enc := gob.NewEncoder(&buf) metrics := make([]plugin.MetricType, len(mts)) for i, m := range mts { mt := plugin.NewMetricType(m.Namespace(), m.Timestamp(), m.Tags(), m.Unit(), m.Data()) metrics[i] = *mt } enc.Encode(metrics) req := controlproxy.GetPubProcReq("snap.gob", buf.Bytes(), "passthru", 1, map[string]ctypes.ConfigValue{}, "my-snowflake-id") reply, err := client.ProcessMetrics(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldEqual, 0) // content to pass to publisher content = reply.Content }) }) //publishmetrics Convey("PublishMetrics", t, func() { Convey("Should error with invalid inputs", func() { req := controlproxy.GetPubProcReq("snap.gob", []byte{}, "bad name", 1, map[string]ctypes.ConfigValue{}, "my-snowflake-id") reply, err := client.PublishMetrics(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldNotEqual, 0) So(reply.Errors[0], ShouldResemble, "bad key") }) // Publish only returns no errors on success Convey("should not error with valid inputs", func() { config := make(map[string]ctypes.ConfigValue) config["file"] = ctypes.ConfigValueStr{Value: "/tmp/grpcservertest.snap"} req := controlproxy.GetPubProcReq("snap.gob", content, "file", 3, config, "my-snowflake-id") reply, err := client.PublishMetrics(context.Background(), req) // we don't expect rpc errors So(err, ShouldBeNil) So(len(reply.Errors), ShouldEqual, 0) }) }) }