示例#1
0
文件: body.go 项目: IRCody/snap
func UnmarshalBody(t string, b []byte) (Body, error) {
	switch t {
	case PluginListType:
		return unmarshalAndHandleError(b, &PluginList{})
	case PluginsLoadedType:
		return unmarshalAndHandleError(b, &PluginsLoaded{})
	case PluginUnloadedType:
		return unmarshalAndHandleError(b, &PluginUnloaded{})
	case PluginReturnedType:
		return unmarshalAndHandleError(b, &PluginReturned{})
	case ScheduledTaskListReturnedType:
		return unmarshalAndHandleError(b, &ScheduledTaskListReturned{})
	case ScheduledTaskReturnedType:
		return unmarshalAndHandleError(b, &ScheduledTaskReturned{})
	case ScheduledTaskType:
		return unmarshalAndHandleError(b, &ScheduledTask{})
	case AddScheduledTaskType:
		return unmarshalAndHandleError(b, &AddScheduledTask{})
	case ScheduledTaskStartedType:
		return unmarshalAndHandleError(b, &ScheduledTaskStarted{})
	case ScheduledTaskStoppedType:
		return unmarshalAndHandleError(b, &ScheduledTaskStopped{})
	case ScheduledTaskRemovedType:
		return unmarshalAndHandleError(b, &ScheduledTaskRemoved{})
	case ScheduledTaskEnabledType:
		return unmarshalAndHandleError(b, &ScheduledTaskEnabled{})
	case MetricReturnedType:
		return unmarshalAndHandleError(b, &MetricReturned{})
	case MetricsReturnedType:
		return unmarshalAndHandleError(b, &MetricsReturned{})
	case ScheduledTaskWatchingEndedType:
		return unmarshalAndHandleError(b, &ScheduledTaskWatchingEnded{})
	case TribeMemberListType:
		return unmarshalAndHandleError(b, &TribeMemberList{})
	case TribeListAgreementType:
		return unmarshalAndHandleError(b, &TribeListAgreement{})
	case TribeAddAgreementType:
		return unmarshalAndHandleError(b, &TribeAddAgreement{})
	case TribeDeleteAgreementType:
		return unmarshalAndHandleError(b, &TribeDeleteAgreement{})
	case TribeMemberShowType:
		return unmarshalAndHandleError(b, &TribeMemberShow{})
	case TribeJoinAgreementType:
		return unmarshalAndHandleError(b, &TribeJoinAgreement{})
	case TribeLeaveAgreementType:
		return unmarshalAndHandleError(b, &TribeLeaveAgreement{})
	case TribeGetAgreementType:
		return unmarshalAndHandleError(b, &TribeGetAgreement{})
	case PluginConfigItemType:
		return unmarshalAndHandleError(b, &PluginConfigItem{*cdata.NewNode()})
	case SetPluginConfigItemType:
		return unmarshalAndHandleError(b, &SetPluginConfigItem{*cdata.NewNode()})
	case DeletePluginConfigItemType:
		return unmarshalAndHandleError(b, &DeletePluginConfigItem{*cdata.NewNode()})
	case ErrorType:
		return unmarshalAndHandleError(b, &Error{})
	default:
		return nil, ErrCannotUnmarshalBody
	}
}
func TestGetMetricConfigItem(t *testing.T) {

	Convey("Get a value of items from Metrics Config with no error", t, func() {
		// create config
		config := cdata.NewNode()
		config.AddItem("dummy_string", ctypes.ConfigValueStr{Value: dummy_str})
		config.AddItem("dummy_bool", ctypes.ConfigValueBool{Value: dummy_bool})
		config.AddItem("dummy_int", ctypes.ConfigValueInt{Value: dummy_int})
		config.AddItem("dummy_float", ctypes.ConfigValueFloat{Value: dummy_float})

		// create metric and set config
		metric := plugin.MetricType{}
		metric.Config_ = config

		Convey("string type of item", func() {
			result, err := GetMetricConfigItem(metric, "dummy_string")
			So(err, ShouldBeNil)
			So(result, ShouldEqual, dummy_str)
		})

		Convey("bool type of item", func() {
			result, err := GetMetricConfigItem(metric, "dummy_bool")
			So(err, ShouldBeNil)
			So(result, ShouldEqual, dummy_bool)
		})

		Convey("int type of item", func() {
			result, err := GetMetricConfigItem(metric, "dummy_int")
			So(err, ShouldBeNil)
			So(result, ShouldEqual, dummy_int)
		})

		Convey("float type of item", func() {
			result, err := GetMetricConfigItem(metric, "dummy_float")
			So(err, ShouldBeNil)
			So(result, ShouldEqual, dummy_float)
		})
	})

	Convey("Try to get a value of items not defined in Metrics Config", t, func() {
		config := cdata.NewNode()
		config.AddItem("foo", ctypes.ConfigValueStr{Value: "foo_val"})
		metric := plugin.MetricType{}
		metric.Config_ = config

		result, err := GetMetricConfigItem(metric, "foo_not_exist")
		So(err, ShouldNotBeNil)
		So(result, ShouldBeNil)
	})

	Convey("No item defined in Metrics Config", t, func() {
		metric := plugin.MetricType{}
		metric.Config_ = cdata.NewNode()

		result, err := GetMetricConfigItem(metric, "foo")
		So(err, ShouldNotBeNil)
		So(result, ShouldBeNil)
	})
}
func TestMesos_getConfig(t *testing.T) {
	log.SetLevel(log.ErrorLevel) // Suppress warning messages from getConfig

	Convey("Get plugin configuration from snap global config", t, func() {
		Convey("When only a master is provided, getConfig() should return only the master value", func() {
			node := cdata.NewNode()
			node.AddItem("master", ctypes.ConfigValueStr{Value: "mesos-master.example.com:5050"})
			snapCfg := plugin.ConfigType{ConfigDataNode: node}

			parsedCfg, err := getConfig(snapCfg)

			So(parsedCfg["master"], ShouldEqual, "mesos-master.example.com:5050")
			So(parsedCfg["agent"], ShouldEqual, "")
			So(err, ShouldBeNil)
		})

		Convey("When only an agent is provided, getConfig() should return only the agent value", func() {
			node := cdata.NewNode()
			node.AddItem("agent", ctypes.ConfigValueStr{Value: "mesos-agent.example.com:5051"})
			snapCfg := plugin.ConfigType{ConfigDataNode: node}

			parsedCfg, err := getConfig(snapCfg)

			So(parsedCfg["master"], ShouldEqual, "")
			So(parsedCfg["agent"], ShouldEqual, "mesos-agent.example.com:5051")
			So(err, ShouldBeNil)
		})

		Convey("When both a master and an agent are provided, getConfig() should return both values", func() {
			node := cdata.NewNode()
			node.AddItem("master", ctypes.ConfigValueStr{Value: "mesos-master.example.com:5050"})
			node.AddItem("agent", ctypes.ConfigValueStr{Value: "mesos-agent.example.com:5051"})
			snapCfg := plugin.ConfigType{ConfigDataNode: node}

			parsedCfg, err := getConfig(snapCfg)

			So(len(parsedCfg), ShouldEqual, 2)
			So(err, ShouldBeNil)
		})

		Convey("When both master and agent are missing, getConfig() should return an error", func() {
			node := cdata.NewNode()
			node.AddItem("foo", ctypes.ConfigValueStr{Value: "bar"})
			snapCfg := plugin.ConfigType{ConfigDataNode: node}

			parsedCfg, err := getConfig(snapCfg)

			So(len(parsedCfg), ShouldEqual, 0)
			So(err, ShouldNotBeNil)
		})
	})
}
func testingConfig() (cfg1 plugin.ConfigType, cfg2 *cdata.ConfigDataNode) {
	cfg1 = plugin.NewPluginConfigType()
	cfg2 = cdata.NewNode()

	cfg1.AddItem("openstack_user", ctypes.ConfigValueStr{Value: "x"})
	cfg1.AddItem("openstack_pass", ctypes.ConfigValueStr{Value: "x"})
	cfg1.AddItem("openstack_tenant", ctypes.ConfigValueStr{Value: "asdf"})
	cfg1.AddItem("openstack_auth_url", ctypes.ConfigValueStr{Value: "x"})

	cfg2.AddItem("openstack_user", ctypes.ConfigValueStr{Value: "x"})
	cfg2.AddItem("openstack_pass", ctypes.ConfigValueStr{Value: "x"})
	cfg2.AddItem("openstack_tenant", ctypes.ConfigValueStr{Value: "asdf"})
	cfg2.AddItem("openstack_auth_url", ctypes.ConfigValueStr{Value: "x"})

	cfg1.AddItem("allocation_ratio_cores", ctypes.ConfigValueFloat{Value: 3})
	cfg1.AddItem("allocation_ratio_ram", ctypes.ConfigValueFloat{Value: 4})
	cfg1.AddItem("reserved_node_cores", ctypes.ConfigValueFloat{Value: 5})
	cfg1.AddItem("reserved_node_ram_mb", ctypes.ConfigValueFloat{Value: 6})

	cfg2.AddItem("allocation_ratio_cores", ctypes.ConfigValueFloat{Value: 3})
	cfg2.AddItem("allocation_ratio_ram", ctypes.ConfigValueFloat{Value: 4})
	cfg2.AddItem("reserved_node_cores", ctypes.ConfigValueFloat{Value: 5})
	cfg2.AddItem("reserved_node_ram_mb", ctypes.ConfigValueFloat{Value: 6})

	return cfg1, cfg2
}
示例#5
0
文件: wmap.go 项目: jcooklin/snap
func configtoConfigDataNode(cmap map[string]interface{}, ns string) (*cdata.ConfigDataNode, error) {
	cdn := cdata.NewNode()
	for ck, cv := range cmap {
		switch v := cv.(type) {
		case string:
			cdn.AddItem(ck, ctypes.ConfigValueStr{Value: v})
		case int:
			cdn.AddItem(ck, ctypes.ConfigValueInt{Value: v})
		case float64:
			//working around the fact that json decodes numbers to floats
			//if we can convert the number to an int without loss it will be an int
			if v == float64(int(v)) {
				cdn.AddItem(ck, ctypes.ConfigValueInt{Value: int(v)})
			} else {
				cdn.AddItem(ck, ctypes.ConfigValueFloat{Value: v})
			}
		case bool:
			cdn.AddItem(ck, ctypes.ConfigValueBool{Value: v})
		default:
			// TODO make sure this is covered in tests!!!
			return nil, errors.New(fmt.Sprintf("Cannot convert config value to config data node: %s=>%+v", ns, v))
		}
	}
	return cdn, nil
}
func setupCfg(endpoint, user, password, tenant string) plugin.ConfigType {
	node := cdata.NewNode()
	node.AddItem("endpoint", ctypes.ConfigValueStr{Value: endpoint})
	node.AddItem("user", ctypes.ConfigValueStr{Value: user})
	node.AddItem("password", ctypes.ConfigValueStr{Value: password})
	node.AddItem("tenant", ctypes.ConfigValueStr{Value: tenant})
	return plugin.ConfigType{ConfigDataNode: node}
}
func TestGetMetricConfigItems(t *testing.T) {

	Convey("Get values of items from Metrics Config with no error", t, func() {

		// create config
		config := cdata.NewNode()
		config.AddItem("dummy_string", ctypes.ConfigValueStr{Value: dummy_str})
		config.AddItem("dummy_bool", ctypes.ConfigValueBool{Value: dummy_bool})
		config.AddItem("dummy_int", ctypes.ConfigValueInt{Value: dummy_int})
		config.AddItem("dummy_float", ctypes.ConfigValueFloat{Value: dummy_float})

		// create metric and set config
		metric := plugin.MetricType{}
		metric.Config_ = config

		names := []string{"dummy_string", "dummy_bool", "dummy_int", "dummy_float"}

		result, err := GetMetricConfigItems(metric, names)
		So(err, ShouldBeNil)
		for _, name := range names {
			So(result[name], ShouldNotBeEmpty)
		}
	})

	Convey("Try to get values of items not defined in Metrics config", t, func() {
		config := cdata.NewNode()
		config.AddItem("foo", ctypes.ConfigValueStr{Value: "foo_val"})
		metric := plugin.MetricType{}
		metric.Config_ = config

		names := []string{"foo1", "foo2"}
		result, err := GetMetricConfigItems(metric, names)
		So(err, ShouldNotBeNil)
		So(result, ShouldBeNil)
	})

	Convey("No item defined in Metrics Config", t, func() {
		metric := plugin.MetricType{}
		metric.Config_ = cdata.NewNode()
		names := []string{"foo", "bar"}
		result, err := GetMetricConfigItems(metric, names)
		So(err, ShouldNotBeNil)
		So(result, ShouldBeNil)
	})
}
示例#8
0
文件: config.go 项目: jcooklin/snap
func newPluginConfig() *pluginConfig {
	return &pluginConfig{
		All:         cdata.NewNode(),
		Collector:   newPluginTypeConfigItem(),
		Processor:   newPluginTypeConfigItem(),
		Publisher:   newPluginTypeConfigItem(),
		pluginCache: make(map[string]*cdata.ConfigDataNode),
	}
}
func getMockMetricConfig() *cdata.ConfigDataNode {
	// mocking metric config
	cfg := cdata.NewNode()
	cfg.AddItem("host", ctypes.ConfigValueStr{Value: "hostname"})
	cfg.AddItem("port", ctypes.ConfigValueInt{Value: 1234})
	cfg.AddItem("user", ctypes.ConfigValueStr{Value: "test"})
	cfg.AddItem("password", ctypes.ConfigValueStr{Value: "passwd"})

	return cfg
}
示例#10
0
文件: metric.go 项目: IRCody/snap
func (p *ConfigType) UnmarshalJSON(data []byte) error {
	cdn := cdata.NewNode()
	dec := json.NewDecoder(bytes.NewReader(data))
	dec.UseNumber()
	if err := dec.Decode(cdn); err != nil {
		return err
	}
	p.ConfigDataNode = cdn
	return nil
}
示例#11
0
文件: metric.go 项目: IRCody/snap
func (p *ConfigType) GobDecode(data []byte) error {
	cdn := cdata.NewNode()
	decoder := gob.NewDecoder(bytes.NewReader(data))
	if err := decoder.Decode(cdn); err != nil {
		return err
	}
	p.ConfigDataNode = cdn

	return nil
}
示例#12
0
func TestPublishMetrics(t *testing.T) {
	Convey("Given an available file publisher plugin", t, func() {
		// adjust HB timeouts for test
		plugin.PingTimeoutLimit = 1
		plugin.PingTimeoutDurationDefault = time.Second * 1

		// Create controller
		config := NewConfig()
		c := New(OptSetConfig(config))
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("TestPublishMetrics", lpe)
		c.pluginRunner.(*runner).monitor.duration = time.Millisecond * 100
		c.Start()
		time.Sleep(1 * time.Second)

		// Load plugin
		_, err := load(c, path.Join(SnapPath, "plugin", "snap-publisher-file"))
		<-lpe.done
		So(err, ShouldBeNil)
		So(len(c.pluginManager.all()), ShouldEqual, 1)
		lp, err2 := c.pluginManager.get("publisher:file:3")
		So(err2, ShouldBeNil)
		So(lp.Name(), ShouldResemble, "file")
		So(lp.ConfigPolicy, ShouldNotBeNil)

		Convey("Subscribe to file publisher with good config", func() {
			n := cdata.NewNode()
			config.Plugins.Publisher.Plugins[lp.Name()] = newPluginConfigItem(optAddPluginConfigItem("file", ctypes.ConfigValueStr{Value: "/tmp/snap-TestPublishMetrics.out"}))
			pool, errp := c.pluginRunner.AvailablePlugins().getOrCreatePool("publisher:file:3")
			So(errp, ShouldBeNil)
			pool.subscribe("1", unboundSubscriptionType)
			err := c.pluginRunner.runPlugin(lp.Details)
			So(err, ShouldBeNil)
			time.Sleep(2500 * time.Millisecond)

			Convey("Publish to file", func() {
				metrics := []plugin.PluginMetricType{
					*plugin.NewPluginMetricType([]string{"foo"}, time.Now(), "", nil, nil, 1),
				}
				var buf bytes.Buffer
				enc := gob.NewEncoder(&buf)
				enc.Encode(metrics)
				contentType := plugin.SnapGOBContentType
				errs := c.PublishMetrics(contentType, buf.Bytes(), "file", 3, n.Table())
				So(errs, ShouldBeNil)
				ap := c.AvailablePlugins()
				So(ap, ShouldNotBeEmpty)
			})
		})
		c.Stop()
		time.Sleep(100 * time.Millisecond)

	})
}
示例#13
0
文件: config.go 项目: jcooklin/snap
func newPluginConfigItem(opts ...pluginConfigOpt) *pluginConfigItem {
	p := &pluginConfigItem{
		ConfigDataNode: cdata.NewNode(),
		Versions:       make(map[int]*cdata.ConfigDataNode),
	}

	for _, opt := range opts {
		opt(p)
	}

	return p
}
func TestSubscriptionGroups_GetSpecifiedDynamic(t *testing.T) {
	log.SetLevel(log.DebugLevel)
	c := New(getTestSGConfig())

	lpe := newLstnToPluginEvents()
	c.eventManager.RegisterHandler("TestSubscriptionGroups_AddRemove", lpe)
	c.Start()

	Convey("Loading a mock collector plugn", t, func() {
		_, err := loadPlg(c, helper.PluginFilePath("snap-plugin-collector-mock1"))
		So(err, ShouldBeNil)
		<-lpe.load

		Convey("Subscription group created for requested metric with specified instance of dynamic element", func() {
			requested := mockRequestedMetric{namespace: core.NewNamespace("intel", "mock").AddDynamicElement("host", "name of the host").AddStaticElement("baz")}
			// specified dynamic element
			requested.Namespace()[2].Value = "host0"
			subsPlugin := mockSubscribedPlugin{
				typeName: core.CollectorPluginType,
				name:     "mock",
				version:  1,
				config:   cdata.NewNode(),
			}
			subsPluginKey := key(subsPlugin)

			sg := newSubscriptionGroups(c)
			So(sg, ShouldNotBeNil)
			sg.Add("task-id", []core.RequestedMetric{requested}, cdata.NewTree(), []core.SubscribedPlugin{subsPlugin})
			<-lpe.sub
			So(len(sg.subscriptionMap), ShouldEqual, 1)
			val, ok := sg.subscriptionMap["task-id"]
			So(ok, ShouldBeTrue)
			So(val, ShouldNotBeNil)

			pluginToMetricMap, serrs, err := sg.Get("task-id")
			So(len(serrs), ShouldEqual, 0)
			So(err, ShouldBeNil)
			So(len(pluginToMetricMap), ShouldEqual, 1)
			So(pluginToMetricMap, ShouldContainKey, subsPluginKey)
			metrics := pluginToMetricMap[subsPluginKey].Metrics()
			So(len(metrics), ShouldEqual, 1)

			pluginToMetricMap, serrs, err = sg.Get("task-fake-id")
			So(len(serrs), ShouldEqual, 0)
			So(err, ShouldNotBeNil)
			So(err, ShouldResemble, ErrSubscriptionGroupDoesNotExist)
			So(pluginToMetricMap, ShouldBeEmpty)
		})
	})
}
示例#15
0
文件: config.go 项目: jcooklin/snap
func (p *pluginConfig) getPluginConfigDataNode(pluginType core.PluginType, name string, ver int) *cdata.ConfigDataNode {
	// check cache
	key := fmt.Sprintf("%d:%s:%d", pluginType, name, ver)
	if res, ok := p.pluginCache[key]; ok {
		return res
	}

	//todo process/interpolate values

	p.pluginCache[key] = cdata.NewNode()
	p.pluginCache[key].Merge(p.All)

	// check for plugin config
	switch pluginType {
	case core.CollectorPluginType:
		p.pluginCache[key].Merge(p.Collector.All)
		if res, ok := p.Collector.Plugins[name]; ok {
			p.pluginCache[key].Merge(res.ConfigDataNode)
			if res2, ok2 := res.Versions[ver]; ok2 {
				p.pluginCache[key].Merge(res2)
			}
		}
	case core.ProcessorPluginType:
		p.pluginCache[key].Merge(p.Processor.All)
		if res, ok := p.Processor.Plugins[name]; ok {
			p.pluginCache[key].Merge(res.ConfigDataNode)
			if res2, ok2 := res.Versions[ver]; ok2 {
				p.pluginCache[key].Merge(res2)
			}
		}
	case core.PublisherPluginType:
		p.pluginCache[key].Merge(p.Publisher.All)
		if res, ok := p.Publisher.Plugins[name]; ok {
			p.pluginCache[key].Merge(res.ConfigDataNode)
			if res2, ok2 := res.Versions[ver]; ok2 {
				p.pluginCache[key].Merge(res2)
			}
		}
	}

	//todo change to debug
	log.WithFields(log.Fields{
		"_block_":            "getPluginConfigDataNode",
		"_module":            "config",
		"config-cache-key":   key,
		"config-cache-value": p.pluginCache[key],
	}).Debug("Getting plugin config")

	return p.pluginCache[key]
}
func TestConfigItems(t *testing.T) {
	names := []string{"dummy_string", "dummy_bool", "dummy_int", "dummy_float"}

	Convey("Get values of configuration items with no error", t, func() {

		Convey("Source: global config", func() {
			//create global config and add item (different types)
			cfg := plugin.NewPluginConfigType()
			cfg.AddItem("dummy_string", ctypes.ConfigValueStr{Value: dummy_str})
			cfg.AddItem("dummy_bool", ctypes.ConfigValueBool{Value: dummy_bool})
			cfg.AddItem("dummy_int", ctypes.ConfigValueInt{Value: dummy_int})
			cfg.AddItem("dummy_float", ctypes.ConfigValueFloat{Value: dummy_float})

			result, err := GetConfigItems(cfg, names...)
			So(err, ShouldBeNil)
			for _, name := range names {
				So(result[name], ShouldNotBeEmpty)
			}
		})

		Convey("Source: metrics config", func() {
			// create metrics config
			config := cdata.NewNode()
			config.AddItem("dummy_string", ctypes.ConfigValueStr{Value: dummy_str})
			config.AddItem("dummy_bool", ctypes.ConfigValueBool{Value: dummy_bool})
			config.AddItem("dummy_int", ctypes.ConfigValueInt{Value: dummy_int})
			config.AddItem("dummy_float", ctypes.ConfigValueFloat{Value: dummy_float})

			// create metric and set config
			metric := plugin.MetricType{}
			metric.Config_ = config

			result, err := GetConfigItems(metric, names...)
			So(err, ShouldBeNil)
			for _, name := range names {
				So(result[name], ShouldNotBeEmpty)
			}
		})
	})

	Convey("Try to get values of items from invalid config (unsupported type)", t, func() {
		invalid_cfg := []string{"invalid", "config", "source"}
		result, err := GetConfigItems(invalid_cfg, names...)
		So(err, ShouldNotBeNil)
		So(result, ShouldBeNil)
	})

}
// setupCfg builds a new ConfigDataNode that specifies the Mesos master and agent host / port
// to use in the integration test(s).
func setupCfg() plugin.ConfigType {
	master := os.Getenv("SNAP_MESOS_MASTER")
	if master == "" {
		master = "127.0.0.1:5050"
	}

	agent := os.Getenv("SNAP_MESOS_AGENT")
	if agent == "" {
		agent = "127.0.0.1:5051"
	}

	node := cdata.NewNode()
	node.AddItem("master", ctypes.ConfigValueStr{Value: master})
	node.AddItem("agent", ctypes.ConfigValueStr{Value: agent})

	return plugin.ConfigType{ConfigDataNode: node}

}
示例#18
0
func (c *collectorJob) Run() {
	log.WithFields(log.Fields{
		"_module":      "scheduler-job",
		"block":        "run",
		"job-type":     "collector",
		"metric-count": len(c.metricTypes),
	}).Debug("starting collector job")
	metrics := make([]core.Metric, len(c.metricTypes))
	for i, rmt := range c.metricTypes {
		config := c.configDataTree.Get(rmt.Namespace())
		if config == nil {
			config = cdata.NewNode()
		}
		metrics[i] = &metric{
			namespace: rmt.Namespace(),
			version:   rmt.Version(),
			config:    config,
		}
	}
	ret, errs := c.collector.CollectMetrics(metrics, c.Deadline())

	log.WithFields(log.Fields{
		"_module":      "scheduler-job",
		"block":        "run",
		"job-type":     "collector",
		"metric-count": len(ret),
	}).Debug("collector run completed")

	c.metrics = ret
	if errs != nil {
		for _, e := range errs {
			log.WithFields(log.Fields{
				"_module":  "scheduler-job",
				"block":    "run",
				"job-type": "collector",
				"error":    e,
			}).Error("collector run error")
		}
		c.errors = errs
	}
	c.replchan <- struct{}{}
}
func TestSubscriptionGroups_AddRemoveDynamic(t *testing.T) {
	log.SetLevel(log.DebugLevel)
	c := New(getTestSGConfig())

	lpe := newLstnToPluginEvents()
	c.eventManager.RegisterHandler("TestSubscriptionGroups_AddRemove", lpe)
	c.Start()

	Convey("Loading a mock collector plugn", t, func() {
		_, err := loadPlg(c, helper.PluginFilePath("snap-plugin-collector-mock1"))
		So(err, ShouldBeNil)
		<-lpe.load

		Convey("Subscription group created for requested metric with wildcards", func() {
			requested := mockRequestedMetric{
				namespace: core.NewNamespace("intel", "mock").AddDynamicElement("wild", "wild description"),
				version:   -1,
			}
			subsPlugin := mockSubscribedPlugin{
				typeName: core.CollectorPluginType,
				name:     "mock",
				version:  1,
				config:   cdata.NewNode(),
			}

			sg := newSubscriptionGroups(c)
			So(sg, ShouldNotBeNil)
			sg.Add("task-id", []core.RequestedMetric{requested}, cdata.NewTree(), []core.SubscribedPlugin{subsPlugin})
			<-lpe.sub
			So(len(sg.subscriptionMap), ShouldEqual, 1)
			val, ok := sg.subscriptionMap["task-id"]
			So(ok, ShouldBeTrue)
			So(val, ShouldNotBeNil)

			serrs := sg.Remove("task-id")
			<-lpe.unsub
			So(len(serrs), ShouldEqual, 0)
			So(len(sg.subscriptionMap), ShouldEqual, 0)
		})
	})
}
示例#20
0
文件: config.go 项目: IRCody/snap
func (s *Server) setPluginConfigItem(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	var err error
	var typ core.PluginType
	styp := p.ByName("type")
	if styp != "" {
		typ, err = getPluginType(styp)
		if err != nil {
			respond(400, rbody.FromError(err), w)
			return
		}
	}

	name := p.ByName("name")
	sver := p.ByName("version")
	var iver int
	if sver != "" {
		if iver, err = strconv.Atoi(sver); err != nil {
			respond(400, rbody.FromError(err), w)
			return
		}
	} else {
		iver = -2
	}

	src := cdata.NewNode()
	errCode, err := core.UnmarshalBody(src, r.Body)
	if errCode != 0 && err != nil {
		respond(400, rbody.FromError(err), w)
		return
	}

	var res cdata.ConfigDataNode
	if styp == "" {
		res = s.mc.MergePluginConfigDataNodeAll(src)
	} else {
		res = s.mc.MergePluginConfigDataNode(typ, name, iver, src)
	}

	item := &rbody.SetPluginConfigItem{ConfigDataNode: res}
	respond(200, item, w)
}
示例#21
0
func (c *collectorPluginProxy) GetMetricTypes(args []byte, reply *[]byte) error {
	defer catchPluginPanic(c.Session.Logger())

	c.Session.Logger().Println("GetMetricTypes called")
	// Reset heartbeat
	c.Session.ResetHeartbeat()

	dargs := &GetMetricTypesArgs{PluginConfig: PluginConfigType{ConfigDataNode: cdata.NewNode()}}
	c.Session.Decode(args, dargs)

	mts, err := c.Plugin.GetMetricTypes(dargs.PluginConfig)
	if err != nil {
		return errors.New(fmt.Sprintf("GetMetricTypes call error : %s", err.Error()))
	}

	r := GetMetricTypesReply{PluginMetricTypes: mts}
	*reply, err = c.Session.Encode(r)
	if err != nil {
		return err
	}

	return nil
}
func TestLibirtPlugin(t *testing.T) {
	Convey("Meta should return metadata for the plugin", t, func() {
		meta := Meta()
		So(meta.Name, ShouldResemble, Name)
		So(meta.Version, ShouldResemble, Version)
		So(meta.Type, ShouldResemble, plugin.CollectorPluginType)
	})

	Convey("Create Osv Collector", t, func() {
		osvCol := NewOsvCollector()
		Convey("So psCol should not be nil", func() {
			So(osvCol, ShouldNotBeNil)
		})
		Convey("So psCol should be of Osv type", func() {
			So(osvCol, ShouldHaveSameTypeAs, &Osv{})
		})
		Convey("osvCol.GetConfigPolicy() should return a config policy", func() {
			configPolicy, _ := osvCol.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{})
			})
		})
	})
	Convey("Join namespace ", t, func() {
		namespace1 := []string{"intel", "osv", "one"}
		namespace2 := []string{}
		Convey("So namespace should equal intel/osv/one", func() {
			So("/intel/osv/one", ShouldResemble, joinNamespace(namespace1))
		})
		Convey("So namespace should equal slash", func() {
			So("/", ShouldResemble, joinNamespace(namespace2))
		})

	})
	Convey("Get URI ", t, func() {
		Convey("So should return 10.1.0.1:8000", func() {
			swagIP := "10.1.0.1"
			swagPort := 8000
			uri := osvRestURL(swagIP, swagPort)
			So("http://10.1.0.1:8000", ShouldResemble, uri)
		})
	})
	Convey("Get Metrics ", t, func() {
		osvCol := NewOsvCollector()
		cfgNode := cdata.NewNode()
		var cfg = plugin.PluginConfigType{
			ConfigDataNode: cfgNode,
		}
		Convey("So should return 187 types of metrics", func() {
			metrics, err := osvCol.GetMetricTypes(cfg)
			So(187, ShouldResemble, len(metrics))
			So(err, ShouldBeNil)
		})
		Convey("So should check namespace", func() {
			metrics, err := osvCol.GetMetricTypes(cfg)
			waitNamespace := joinNamespace(metrics[0].Namespace())
			wait := regexp.MustCompile(`^/osv/trace/virtio/virtio_wait_for_queue`)
			So(true, ShouldEqual, wait.MatchString(waitNamespace))
			So(err, ShouldBeNil)

		})

	})
	Convey("Get Metrics ", t, func() {
		osvCol := NewOsvCollector()
		cfgNode := cdata.NewNode()
		cfgNode.AddItem("swagIP", ctypes.ConfigValueStr{Value: "192.168.192.200"})
		cfgNode.AddItem("swagPort", ctypes.ConfigValueInt{Value: 8000})

		httpmock.Activate()
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder("GET", "http://192.168.192.200:8000/os/memory/free",
			func(req *http.Request) (*http.Response, error) {
				resp := httpmock.NewStringResponse(200, "20000")
				return resp, nil

			},
		)
		httpmock.RegisterResponder("GET", "http://192.168.192.200:8000/trace/count",
			func(req *http.Request) (*http.Response, error) {
				resp := httpmock.NewStringResponse(200, `{"time_ms": 144123232, "list": []}`)
				return resp, nil

			},
		)
		defer httpmock.DeactivateAndReset()
		httpmock.RegisterResponder("GET", "http://192.168.192.200:8000/trace/count",
			func(req *http.Request) (*http.Response, error) {
				resp := httpmock.NewStringResponse(200, `{"time_ms": 144123232, "list": [{"name": "waitqueue_wake_one", "count": 1000}]}`)
				return resp, nil

			},
		)
		Convey("So should get memory metrics", func() {
			metrics := []plugin.PluginMetricType{{
				Namespace_: []string{"osv", "memory", "free"},
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(len(collect), ShouldResemble, 1)

		})
		Convey("So should get cpu metrics", func() {
			metrics := []plugin.PluginMetricType{{
				Namespace_: []string{"osv", "cpu", "cputime"},
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(collect[0].Data_, ShouldResemble, "144123232")
			So(len(collect), ShouldResemble, 1)

		})
		Convey("So should get trace metrics", func() {
			metrics := []plugin.PluginMetricType{{
				Namespace_: []string{"osv", "trace", "wait", "waitqueue_wake_one"},
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(collect[0].Data_, ShouldResemble, "1000")
			So(len(collect), ShouldResemble, 1)

		})

	})
}
func TestLibirtPlugin(t *testing.T) {
	httpmock.Mock = true

	Convey("Meta should return metadata for the plugin", t, func() {
		meta := Meta()
		So(meta.Name, ShouldResemble, Name)
		So(meta.Version, ShouldResemble, Version)
		So(meta.Type, ShouldResemble, plugin.CollectorPluginType)
	})

	Convey("Create Osv Collector", t, func() {
		osvCol := NewOsvCollector()
		Convey("So psCol should not be nil", func() {
			So(osvCol, ShouldNotBeNil)
		})
		Convey("So psCol should be of Osv type", func() {
			So(osvCol, ShouldHaveSameTypeAs, &Osv{})
		})
		Convey("osvCol.GetConfigPolicy() should return a config policy", func() {
			configPolicy, _ := osvCol.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{})
			})
		})
	})
	Convey("Get URI ", t, func() {
		Convey("So should return 10.1.0.1:8000", func() {
			swagIP := "10.1.0.1"
			swagPort := 8000
			uri := osvRestURL(swagIP, swagPort)
			So("http://10.1.0.1:8000", ShouldResemble, uri)
		})
	})
	Convey("Get Metrics ", t, func() {
		osvCol := NewOsvCollector()
		cfgNode := cdata.NewNode()
		var cfg = plugin.ConfigType{
			ConfigDataNode: cfgNode,
		}
		Convey("So should return 187 types of metrics", func() {
			metrics, err := osvCol.GetMetricTypes(cfg)
			So(187, ShouldResemble, len(metrics))
			So(err, ShouldBeNil)
		})
		Convey("So should check namespace", func() {
			metrics, err := osvCol.GetMetricTypes(cfg)
			waitNamespace := metrics[0].Namespace().String()
			wait := regexp.MustCompile(`^/intel/osv/trace/virtio/virtio_wait_for_queue`)
			So(true, ShouldEqual, wait.MatchString(waitNamespace))
			So(err, ShouldBeNil)

		})

	})
	Convey("Get Metrics ", t, func() {
		osvCol := NewOsvCollector()
		cfgNode := cdata.NewNode()
		cfgNode.AddItem("swagIP", ctypes.ConfigValueStr{Value: "192.168.192.200"})
		cfgNode.AddItem("swagPort", ctypes.ConfigValueInt{Value: 8000})

		defer httpmock.ResetResponders()
		httpmock.RegisterResponder("GET", "http://192.168.192.200:8000/os/memory/free", "20000", 200)
		httpmock.RegisterResponder("GET", "http://192.168.192.200:8000/trace/count",
			`{"time_ms": 144123232, "list": [{"name": "waitqueue_wake_one", "count": 1000}]}`, 200)

		Convey("So should get memory metrics", func() {
			metrics := []plugin.MetricType{{
				Namespace_: core.NewNamespace("intel", "osv", "memory", "free"),
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(len(collect), ShouldResemble, 1)

		})
		Convey("So should get cpu metrics", func() {
			metrics := []plugin.MetricType{{
				Namespace_: core.NewNamespace("intel", "osv", "cpu", "cputime"),
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(collect[0].Data_, ShouldEqual, 144123232)
			So(len(collect), ShouldEqual, 1)

		})
		Convey("So should get trace metrics", func() {
			metrics := []plugin.MetricType{{
				Namespace_: core.NewNamespace("intel", "osv", "trace", "wait", "waitqueue_wake_one"),
				Config_:    cfgNode,
			}}
			collect, err := osvCol.CollectMetrics(metrics)
			So(err, ShouldBeNil)
			So(collect[0].Data_, ShouldNotBeNil)
			So(collect[0].Data_, ShouldEqual, 1000)
			So(len(collect), ShouldEqual, 1)

		})

	})
}
示例#24
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.PluginMetricType{
					Namespace_: []string{"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.PluginMetricType{
					Namespace_: []string{"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.NewPluginMetricType([]string{"foo", "bar"}, time.Now(), "", nil, nil, 1)
			b, _ := json.Marshal([]plugin.PluginMetricType{*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.PluginMetricType
			err = json.Unmarshal(content, &pmts)
			So(err, ShouldBeNil)
			So(len(pmts), ShouldEqual, 1)
			So(pmts[0].Data(), ShouldEqual, 1)
			So(pmts[0].Namespace(), ShouldResemble, []string{"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.NewPluginMetricType([]string{"foo", "bar"}, time.Now(), "", nil, nil, 1)
			b, _ := json.Marshal([]plugin.PluginMetricType{*pmt})
			err := p.Publish(plugin.SnapJSONContentType, b, nil)
			So(err, ShouldBeNil)
		})

	})
}
示例#25
0
func TestPluginRestCalls(t *testing.T) {
	CompressedUpload = false
	Convey("REST API functional V1", t, func() {
		Convey("Load Plugin - POST - /v1/plugins", func() {
			Convey("a single plugin loads", func() {
				// This test alone tests gzip. Saves on test time.
				CompressedUpload = true
				r := startAPI(getDefaultMockConfig())
				port := r.port
				col := core.CollectorPluginType
				pub := core.PublisherPluginType
				Convey("A global plugin config is added for all plugins", func() {
					cdn := cdata.NewNode()
					cdn.AddItem("password", ctypes.ConfigValueStr{Value: "p@ssw0rd"})
					r := setPluginConfigItem(port, "", "", "", cdn)
					So(r.Body, ShouldHaveSameTypeAs, &rbody.SetPluginConfigItem{})
					r1 := r.Body.(*rbody.SetPluginConfigItem)
					So(r1.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"})

					r2 := getPluginConfigItem(port, &col, "", "")
					So(r2.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
					r3 := r2.Body.(*rbody.PluginConfigItem)
					So(len(r3.Table()), ShouldEqual, 1)
					So(r3.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"})

					Convey("A plugin config is added for all publishers", func() {
						cdn := cdata.NewNode()
						cdn.AddItem("user", ctypes.ConfigValueStr{Value: "john"})
						r := setPluginConfigItem(port, core.PublisherPluginType.String(), "", "", cdn)
						So(r.Body, ShouldHaveSameTypeAs, &rbody.SetPluginConfigItem{})
						r1 := r.Body.(*rbody.SetPluginConfigItem)
						So(r1.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"})
						So(len(r1.Table()), ShouldEqual, 2)

						Convey("A plugin config is added for all versions of a publisher", func() {
							cdn := cdata.NewNode()
							cdn.AddItem("path", ctypes.ConfigValueStr{Value: "/usr/local/influxdb/bin"})
							r := setPluginConfigItem(port, "2", "influxdb", "", cdn)
							So(r.Body, ShouldHaveSameTypeAs, &rbody.SetPluginConfigItem{})
							r1 := r.Body.(*rbody.SetPluginConfigItem)
							So(r1.Table()["path"], ShouldResemble, ctypes.ConfigValueStr{Value: "/usr/local/influxdb/bin"})
							So(len(r1.Table()), ShouldEqual, 3)

							Convey("A plugin config is added for a specific version of a publisher", func() {
								cdn := cdata.NewNode()
								cdn.AddItem("rate", ctypes.ConfigValueFloat{Value: .8})
								r := setPluginConfigItem(port, core.PublisherPluginType.String(), "influxdb", "1", cdn)
								So(r.Body, ShouldHaveSameTypeAs, &rbody.SetPluginConfigItem{})
								r1 := r.Body.(*rbody.SetPluginConfigItem)
								So(r1.Table()["rate"], ShouldResemble, ctypes.ConfigValueFloat{Value: .8})
								So(len(r1.Table()), ShouldEqual, 4)

								r2 := getPluginConfigItem(port, &pub, "", "")
								So(r2.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
								r3 := r2.Body.(*rbody.PluginConfigItem)
								So(len(r3.Table()), ShouldEqual, 2)

								r4 := getPluginConfigItem(port, &pub, "influxdb", "1")
								So(r4.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
								r5 := r4.Body.(*rbody.PluginConfigItem)
								So(len(r5.Table()), ShouldEqual, 4)

								Convey("A global plugin config field is deleted", func() {
									r := deletePluginConfigItem(port, "", "", "", []string{"password"})
									So(r.Body, ShouldHaveSameTypeAs, &rbody.DeletePluginConfigItem{})
									r1 := r.Body.(*rbody.DeletePluginConfigItem)
									So(len(r1.Table()), ShouldEqual, 0)

									r2 := setPluginConfigItem(port, core.PublisherPluginType.String(), "influxdb", "", cdn)
									So(r2.Body, ShouldHaveSameTypeAs, &rbody.SetPluginConfigItem{})
									r3 := r2.Body.(*rbody.SetPluginConfigItem)
									So(len(r3.Table()), ShouldEqual, 3)
								})
							})
						})
					})
				})

			})
			Convey("Plugin config is set at startup", func() {
				cfg := getDefaultMockConfig()
				err := cfgfile.Read("../../examples/configs/snap-config-sample.json", &cfg, MOCK_CONSTRAINTS)
				So(err, ShouldBeNil)
				if len(SNAP_AUTODISCOVER_PATH) == 0 {
					if len(SNAP_PATH) != 0 {
						SNAP_AUTODISCOVER_PATH = fmt.Sprintf("%s/plugin", SNAP_PATH)
						log.Warning(fmt.Sprintf("SNAP_AUTODISCOVER_PATH has been set to SNAP_PATH/plugin (%s). This might cause test failures", SNAP_AUTODISCOVER_PATH))
					}
				} else {
					log.Warning(fmt.Sprintf("SNAP_AUTODISCOVER_PATH is set to %s. This might cause test failures", SNAP_AUTODISCOVER_PATH))
				}
				cfg.Control.AutoDiscoverPath = SNAP_AUTODISCOVER_PATH
				r := startAPI(cfg)
				port := r.port
				col := core.CollectorPluginType

				Convey("Gets the collector config by name and version", func() {
					r := getPluginConfigItem(port, &col, "pcm", "1")
					So(r.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
					r1 := r.Body.(*rbody.PluginConfigItem)
					So(r1.Table()["path"], ShouldResemble, ctypes.ConfigValueStr{Value: "/usr/local/pcm/bin"})
					So(r1.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "john"})
					So(len(r1.Table()), ShouldEqual, 6)
				})
				Convey("Gets the config for a collector by name", func() {
					r := getPluginConfigItem(port, &col, "pcm", "")
					So(r.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
					r1 := r.Body.(*rbody.PluginConfigItem)
					So(r1.Table()["path"], ShouldResemble, ctypes.ConfigValueStr{Value: "/usr/local/pcm/bin"})
					So(r1.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "jane"})
					So(len(r1.Table()), ShouldEqual, 3)
				})
				Convey("Gets the config for all collectors", func() {
					r := getPluginConfigItem(port, &col, "", "")
					So(r.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
					r1 := r.Body.(*rbody.PluginConfigItem)
					So(r1.Table()["user"], ShouldResemble, ctypes.ConfigValueStr{Value: "jane"})
					So(r1.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"})
					So(len(r1.Table()), ShouldEqual, 2)
				})
				Convey("Gets the config for all plugins", func() {
					r := getPluginConfigItem(port, nil, "", "")
					So(r.Body, ShouldHaveSameTypeAs, &rbody.PluginConfigItem{})
					r1 := r.Body.(*rbody.PluginConfigItem)
					So(r1.Table()["password"], ShouldResemble, ctypes.ConfigValueStr{Value: "p@ssw0rd"})
					So(len(r1.Table()), ShouldEqual, 1)
				})
			})
		})

		Convey("Enable task - put - /v1/tasks/:id/enable", func() {
			Convey("Enable a running task", func(c C) {
				r := startAPI(getDefaultMockConfig())
				port := r.port

				uploadPlugin(MOCK_PLUGIN_PATH2, port)
				uploadPlugin(FILE_PLUGIN_PATH, port)

				r1 := createTask("1.json", "yeti", "1s", true, port)
				So(r1.Body, ShouldHaveSameTypeAs, new(rbody.AddScheduledTask))
				plr1 := r1.Body.(*rbody.AddScheduledTask)

				id := plr1.ID

				r2 := startTask(id, port)
				So(r2.Body, ShouldHaveSameTypeAs, new(rbody.ScheduledTaskStarted))
				plr2 := r2.Body.(*rbody.ScheduledTaskStarted)
				So(plr2.ID, ShouldEqual, id)

				r4 := enableTask(id, port)
				So(r4.Body, ShouldHaveSameTypeAs, new(rbody.Error))
				plr4 := r4.Body.(*rbody.Error)
				So(plr4.ErrorMessage, ShouldEqual, "Task must be disabled")
			})
		})
	})
}
示例#26
0
func TestCollectMetrics(t *testing.T) {
	Convey("given a loaded plugin", t, func() {
		// adjust HB timeouts for test
		plugin.PingTimeoutLimit = 1
		plugin.PingTimeoutDurationDefault = time.Second * 1

		// Create controller
		config := NewConfig()
		config.Plugins.All.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})
		c := New(OptSetConfig(config))
		c.pluginRunner.(*runner).monitor.duration = time.Millisecond * 100
		c.Start()
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("Control.PluginLoaded", lpe)

		// Add a global plugin config
		c.Config.Plugins.Collector.Plugins["mock"] = newPluginConfigItem(optAddPluginConfigItem("test", ctypes.ConfigValueBool{Value: true}))

		// Load plugin
		load(c, JSONRPCPluginPath)
		<-lpe.done
		mts, err := c.MetricCatalog()
		So(err, ShouldBeNil)
		So(len(mts), ShouldEqual, 4)

		cd := cdata.NewNode()
		cd.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})

		m := []core.Metric{}
		m1 := MockMetricType{
			namespace: []string{"intel", "mock", "foo"},
			cfg:       cd,
		}
		m2 := MockMetricType{
			namespace: []string{"intel", "mock", "bar"},
			cfg:       cd,
		}
		m3 := MockMetricType{
			namespace: []string{"intel", "mock", "test"},
			cfg:       cd,
		}

		// retrieve loaded plugin
		lp, err := c.pluginManager.get("collector:mock:1")
		So(err, ShouldBeNil)
		So(lp, ShouldNotBeNil)
		Convey("create a pool, add subscriptions and start plugins", func() {
			pool, errp := c.pluginRunner.AvailablePlugins().getOrCreatePool("collector:mock:1")
			So(errp, ShouldBeNil)
			pool.subscribe("1", unboundSubscriptionType)
			err = c.pluginRunner.runPlugin(lp.Details)
			So(err, ShouldBeNil)
			pool.subscribe("2", unboundSubscriptionType)
			err = c.pluginRunner.runPlugin(lp.Details)
			So(err, ShouldBeNil)
			m = append(m, m1, m2, m3)
			Convey("collect metrics", func() {
				for x := 0; x < 4; x++ {
					cr, err := c.CollectMetrics(m, time.Now().Add(time.Second*1))
					So(err, ShouldBeNil)
					for i := range cr {
						So(cr[i].Data(), ShouldContainSubstring, "The mock collected data!")
						So(cr[i].Data(), ShouldContainSubstring, "test=true")
					}
				}
				ap := c.AvailablePlugins()
				So(ap, ShouldNotBeEmpty)
				So(pool.strategy.String(), ShouldEqual, plugin.DefaultRouting.String())
				So(len(pool.plugins), ShouldEqual, 2)
				for _, p := range pool.plugins {
					So(p.hitCount, ShouldEqual, 2)
					So(p.hitCount, ShouldEqual, 2)
				}
				c.Stop()
			})
		})
	})

	// Not sure what this was supposed to test, because it's actually testing nothing
	SkipConvey("Pool", t, func() {
		// adjust HB timeouts for test
		plugin.PingTimeoutLimit = 1
		plugin.PingTimeoutDurationDefault = time.Second * 1
		// Create controller
		c := New()
		c.pluginRunner.(*runner).monitor.duration = time.Millisecond * 100
		c.Start()
		load(c, PluginPath)
		m := []core.Metric{}
		c.CollectMetrics(m, time.Now().Add(time.Second*60))
		c.Stop()
		time.Sleep(100 * time.Millisecond)
	})
}
示例#27
0
func TestCollectDynamicMetrics(t *testing.T) {
	Convey("given a plugin using the native client", t, func() {
		config := NewConfig()
		config.Plugins.All.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})
		c := New(OptSetConfig(config), CacheExpiration(time.Second*1))
		c.Start()
		So(strategy.GlobalCacheExpiration, ShouldResemble, time.Second*1)
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("Control.PluginLoaded", lpe)
		_, e := load(c, PluginPath)
		Convey("Loading native client plugin", func() {
			Convey("Should not error", func() {
				So(e, ShouldBeNil)
			})
		})
		if e != nil {
			t.FailNow()
		}
		<-lpe.done
		_, e = load(c, JSONRPCPluginPath)
		Convey("Loading JSONRPC client plugin", func() {
			Convey("Should not error", func() {
				So(e, ShouldBeNil)
			})
		})
		if e != nil {
			t.FailNow()
		}
		<-lpe.done
		cd := cdata.NewNode()
		metrics, err := c.metricCatalog.Fetch([]string{})
		So(err, ShouldBeNil)
		So(len(metrics), ShouldEqual, 6)
		m, err := c.metricCatalog.Get([]string{"intel", "mock", "*", "baz"}, 2)
		So(err, ShouldBeNil)
		So(m, ShouldNotBeNil)
		jsonm, err := c.metricCatalog.Get([]string{"intel", "mock", "*", "baz"}, 1)
		So(err, ShouldBeNil)
		So(jsonm, ShouldNotBeNil)
		metric, errs := c.validateMetricTypeSubscription(m, cd)
		So(errs, ShouldBeNil)
		So(metric, ShouldNotBeNil)
		Convey("collects metrics from plugin using native client", func() {
			lp, err := c.pluginManager.get("collector:mock:2")
			So(err, ShouldBeNil)
			So(lp, ShouldNotBeNil)
			pool, errp := c.pluginRunner.AvailablePlugins().getOrCreatePool("collector:mock:2")
			So(errp, ShouldBeNil)
			So(pool, ShouldNotBeNil)
			ttl, err := pool.CacheTTL()
			So(err, ShouldResemble, ErrPoolEmpty)
			So(ttl, ShouldEqual, 0)
			pool.subscribe("1", unboundSubscriptionType)
			err = c.pluginRunner.runPlugin(lp.Details)
			So(err, ShouldBeNil)
			ttl, err = pool.CacheTTL()
			So(err, ShouldBeNil)
			// The minimum TTL advertised by the plugin is 100ms therefore the TTL for the
			// pool should be the global cache expiration
			So(ttl, ShouldEqual, strategy.GlobalCacheExpiration)
			mts, errs := c.CollectMetrics([]core.Metric{m}, time.Now().Add(time.Second*1))
			hits, err := pool.CacheHits(core.JoinNamespace(m.namespace), 2)
			So(err, ShouldBeNil)
			So(hits, ShouldEqual, 0)
			So(errs, ShouldBeNil)
			So(len(mts), ShouldEqual, 10)
			mts, errs = c.CollectMetrics([]core.Metric{m}, time.Now().Add(time.Second*1))
			hits, err = pool.CacheHits(core.JoinNamespace(m.namespace), 2)
			So(err, ShouldBeNil)
			So(hits, ShouldEqual, 1)
			So(errs, ShouldBeNil)
			So(len(mts), ShouldEqual, 10)
			pool.unsubscribe("1")
			Convey("collects metrics from plugin using httpjson client", func() {
				lp, err := c.pluginManager.get("collector:mock:1")
				So(err, ShouldBeNil)
				So(lp, ShouldNotBeNil)
				pool, errp := c.pluginRunner.AvailablePlugins().getOrCreatePool("collector:mock:1")
				So(errp, ShouldBeNil)
				So(pool, ShouldNotBeNil)
				ttl, err := pool.CacheTTL()
				So(err, ShouldResemble, ErrPoolEmpty)
				So(ttl, ShouldEqual, 0)
				pool.subscribe("1", unboundSubscriptionType)
				err = c.pluginRunner.runPlugin(lp.Details)
				So(err, ShouldBeNil)
				ttl, err = pool.CacheTTL()
				So(err, ShouldBeNil)
				So(ttl, ShouldEqual, 1100*time.Millisecond)
				mts, errs := c.CollectMetrics([]core.Metric{jsonm}, time.Now().Add(time.Second*1))
				hits, err := pool.CacheHits(core.JoinNamespace(jsonm.namespace), jsonm.version)
				So(pool.subscriptionCount(), ShouldEqual, 1)
				So(pool.strategy, ShouldNotBeNil)
				So(len(mts), ShouldBeGreaterThan, 0)
				So(err, ShouldBeNil)
				So(hits, ShouldEqual, 0)
				So(errs, ShouldBeNil)
				So(len(mts), ShouldEqual, 10)
				mts, errs = c.CollectMetrics([]core.Metric{jsonm}, time.Now().Add(time.Second*1))
				hits, err = pool.CacheHits(core.JoinNamespace(m.namespace), 1)
				So(err, ShouldBeNil)
				So(hits, ShouldEqual, 1)
				So(errs, ShouldBeNil)
				So(len(mts), ShouldEqual, 10)
				So(pool.AllCacheHits(), ShouldEqual, 1)
				So(pool.AllCacheMisses(), ShouldEqual, 1)
				pool.unsubscribe("1")
				c.Stop()
				time.Sleep(100 * time.Millisecond)
			})
		})
	})
}
示例#28
0
func TestMetricConfig(t *testing.T) {
	Convey("required config provided by task", t, func() {
		c := New()
		c.Start()
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("Control.PluginLoaded", lpe)
		load(c, JSONRPCPluginPath)
		<-lpe.done
		cd := cdata.NewNode()
		m1 := MockMetricType{
			namespace: []string{"intel", "mock", "foo"},
		}
		metric, errs := c.validateMetricTypeSubscription(m1, cd)
		Convey("So metric should not be valid without config", func() {
			So(metric, ShouldBeNil)
			So(errs, ShouldNotBeNil)
		})
		cd.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})
		metric, errs = c.validateMetricTypeSubscription(m1, cd)
		Convey("So metric should be valid with config", func() {
			So(errs, ShouldBeNil)
			So(metric, ShouldNotBeNil)
		})
		c.Stop()
		time.Sleep(100 * time.Millisecond)
	})
	Convey("nil config provided by task", t, func() {
		config := NewConfig()
		config.Plugins.All.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})
		c := New(OptSetConfig(config))
		c.Start()
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("Control.PluginLoaded", lpe)
		load(c, JSONRPCPluginPath)
		<-lpe.done
		var cd *cdata.ConfigDataNode
		m1 := MockMetricType{
			namespace: []string{"intel", "mock", "foo"},
		}
		metric, errs := c.validateMetricTypeSubscription(m1, cd)
		Convey("So metric should be valid with config", func() {
			So(errs, ShouldBeNil)
			So(metric, ShouldNotBeNil)
		})
		c.Stop()
		time.Sleep(100 * time.Millisecond)
	})
	Convey("required config provided by global plugin config", t, func() {
		config := NewConfig()
		config.Plugins.All.AddItem("password", ctypes.ConfigValueStr{Value: "testval"})
		c := New(OptSetConfig(config))
		c.Start()
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("Control.PluginLoaded", lpe)
		load(c, JSONRPCPluginPath)
		<-lpe.done
		cd := cdata.NewNode()
		m1 := MockMetricType{
			namespace: []string{"intel", "mock", "foo"},
			ver:       1,
		}
		metric, errs := c.validateMetricTypeSubscription(m1, cd)
		Convey("So metric should be valid with config", func() {
			So(errs, ShouldBeNil)
			So(metric, ShouldNotBeNil)
		})
		c.Stop()
		time.Sleep(100 * time.Millisecond)
	})
}
示例#29
0
func TestProcessMetrics(t *testing.T) {
	Convey("Given an available file processor plugin", t, func() {
		// adjust HB timeouts for test
		plugin.PingTimeoutLimit = 1
		plugin.PingTimeoutDurationDefault = time.Second * 1

		// Create controller
		c := New()
		lpe := newListenToPluginEvent()
		c.eventManager.RegisterHandler("TestProcessMetrics", lpe)
		c.pluginRunner.(*runner).monitor.duration = time.Millisecond * 100
		c.Start()
		time.Sleep(1 * time.Second)
		c.Config.Plugins.Processor.Plugins["passthru"] = newPluginConfigItem(optAddPluginConfigItem("test", ctypes.ConfigValueBool{Value: true}))

		// Load plugin
		_, err := load(c, path.Join(SnapPath, "plugin", "snap-processor-passthru"))
		<-lpe.done
		So(err, ShouldBeNil)
		So(len(c.pluginManager.all()), ShouldEqual, 1)
		lp, err2 := c.pluginManager.get("processor:passthru:1")
		So(err2, ShouldBeNil)
		So(lp.Name(), ShouldResemble, "passthru")
		So(lp.ConfigPolicy, ShouldNotBeNil)

		Convey("Subscribe to passthru processor with good config", func() {
			n := cdata.NewNode()
			pool, errp := c.pluginRunner.AvailablePlugins().getOrCreatePool("processor:passthru:1")
			So(errp, ShouldBeNil)
			pool.subscribe("1", unboundSubscriptionType)
			err := c.pluginRunner.runPlugin(lp.Details)
			So(err, ShouldBeNil)
			time.Sleep(2500 * time.Millisecond)

			Convey("process metrics", func() {
				metrics := []plugin.PluginMetricType{
					*plugin.NewPluginMetricType([]string{"foo"}, time.Now(), "", nil, nil, 1),
				}
				var buf bytes.Buffer
				enc := gob.NewEncoder(&buf)
				enc.Encode(metrics)
				contentType := plugin.SnapGOBContentType
				_, ct, errs := c.ProcessMetrics(contentType, buf.Bytes(), "passthru", 1, n.Table())
				So(errs, ShouldBeEmpty)
				mts := []plugin.PluginMetricType{}
				dec := gob.NewDecoder(bytes.NewBuffer(ct))
				err := dec.Decode(&mts)
				So(err, ShouldBeNil)
				So(mts[0].Data_, ShouldEqual, 2)
				So(errs, ShouldBeNil)
			})
		})

		Convey("Count()", func() {
			pmt := &pluginMetricTypes{}
			count := pmt.Count()
			So(count, ShouldResemble, 0)

		})
		c.Stop()
		time.Sleep(100 * time.Millisecond)

	})
}
示例#30
0
文件: metric.go 项目: IRCody/snap
func NewPluginConfigType() ConfigType {
	return ConfigType{
		ConfigDataNode: cdata.NewNode(),
	}
}