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)
		})
	})
}
Example #5
0
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)
		})
	})
}
Example #9
0
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()
Example #11
0
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)

		})

	})
}
Example #18
0
// 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)
		})
	})
}