Example #1
0
func (pc *ControlGRPCServer) SubscribeDeps(ctx context.Context, r *rpc.SubscribeDepsRequest) (*rpc.SubscribeDepsReply, error) {
	plugins := common.ToSubPlugins(r.Plugins)
	configTree := cdata.NewTree()
	requested := common.MetricToRequested(r.Requested)
	serrors := pc.control.SubscribeDeps(r.TaskId, requested, plugins, configTree)
	return &rpc.SubscribeDepsReply{Errors: common.NewErrors(serrors)}, nil
}
Example #2
0
func (pc *ControlGRPCServer) ValidateDeps(ctx context.Context, r *rpc.ValidateDepsRequest) (*rpc.ValidateDepsReply, error) {
	metrics := common.ToRequestedMetrics(r.Metrics)
	plugins := common.ToSubPlugins(r.Plugins)
	configTree := cdata.NewTree()
	serrors := pc.control.ValidateDeps(metrics, plugins, configTree)
	return &rpc.ValidateDepsReply{Errors: common.NewErrors(serrors)}, nil
}
Example #3
0
func TestCollectorJob(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	cdt := cdata.NewTree()
	//TODO: kromar do something with tags?
	tags := map[string]map[string]string{}
	Convey("newCollectorJob()", t, func() {
		Convey("it returns an init-ed collectorJob", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj, ShouldHaveSameTypeAs, &collectorJob{})
		})
	})
	Convey("StartTime()", t, func() {
		Convey("it should return the job starttime", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj.StartTime(), ShouldHaveSameTypeAs, time.Now())
		})
	})
	Convey("Deadline()", t, func() {
		Convey("it should return the job daedline", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj.Deadline(), ShouldResemble, cj.(*collectorJob).deadline)
		})
	})
	Convey("Type()", t, func() {
		Convey("it should return the job type", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj.Type(), ShouldEqual, collectJobType)
		})
	})
	Convey("Errors()", t, func() {
		Convey("it should return the errors from the job", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj.Errors(), ShouldResemble, []error{})
		})
	})
	Convey("AddErrors()", t, func() {
		Convey("it should append errors to the job", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			So(cj.Errors(), ShouldResemble, []error{})

			e1 := errors.New("1")
			e2 := errors.New("2")
			e3 := errors.New("3")

			cj.AddErrors(e1)
			So(cj.Errors(), ShouldResemble, []error{e1})
			cj.AddErrors(e2, e3)
			So(cj.Errors(), ShouldResemble, []error{e1, e2, e3})
		})
	})
	Convey("Run()", t, func() {
		Convey("it should complete without errors", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt, "taskid", tags)
			cj.(*collectorJob).Run()
			So(cj.Errors(), ShouldResemble, []error{})
		})
	})
}
Example #4
0
func TestCollectorJob(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	cdt := cdata.NewTree()
	Convey("newCollectorJob()", t, func() {
		Convey("it returns an init-ed collectorJob", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj, ShouldHaveSameTypeAs, &collectorJob{})
		})
	})
	Convey("StartTime()", t, func() {
		Convey("it should return the job starttime", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj.StartTime(), ShouldHaveSameTypeAs, time.Now())
		})
	})
	Convey("Deadline()", t, func() {
		Convey("it should return the job daedline", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj.Deadline(), ShouldResemble, cj.(*collectorJob).deadline)
		})
	})
	Convey("Type()", t, func() {
		Convey("it should return the job type", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj.Type(), ShouldEqual, collectJobType)
		})
	})
	Convey("ReplChan()", t, func() {
		Convey("it should return the reply channel", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj.ReplChan(), ShouldHaveSameTypeAs, make(chan struct{}))
		})
	})
	// Convey("Metrics()", t, func() {
	// 	Convey("it should return the job metrics", func() {
	// 		cj := newCollectorJob([]core.MetricType{}, defaultDeadline, &mockCollector{})
	// 		So(cj.Metrics(), ShouldResemble, []core.Metric{})
	// 	})
	// })
	Convey("Errors()", t, func() {
		Convey("it should return the errors from the job", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			So(cj.Errors(), ShouldResemble, []error{})
		})
	})
	Convey("Run()", t, func() {
		Convey("it should reply on the reply chan", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			go cj.(*collectorJob).Run()
			<-cj.(*collectorJob).replchan
			So(cj.Errors(), ShouldResemble, []error{})
		})
	})
}
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)
		})
	})
}
Example #6
0
// GetConfigTree converts config data for collection node in wmap into a proper cdata.ConfigDataTree
func (c *CollectWorkflowMapNode) GetConfigTree() (*cdata.ConfigDataTree, error) {
	cdt := cdata.NewTree()
	// Iterate over config and attempt to convert into data nodes in the tree
	for ns_, cmap := range c.Config {

		ns := strings.Split(ns_, "/")[1:]
		cdn, err := configtoConfigDataNode(cmap, ns_)
		if err != nil {
			return nil, err
		}
		cdt.Add(ns, cdn)
	}
	return cdt, nil
}
Example #7
0
func TestValidateDeps(t *testing.T) {
	Convey("RPC client errors", t, func() {
		proxy := ControlProxy{Client: mockClient{RpcErr: true}}
		errs := proxy.ValidateDeps([]core.RequestedMetric{}, []core.SubscribedPlugin{}, cdata.NewTree())
		So(errs, ShouldNotBeNil)
		So(len(errs), ShouldBeGreaterThan, 0)
		Convey("So the error should be passed through", func() {
			So(errs[0].Error(), ShouldResemble, rpcErr.Error())
		})
	})

	Convey("Control.ValidateDeps returns an error", t, func() {
		reply := &rpc.ValidateDepsReply{
			Errors: []*common.SnapError{&common.SnapError{ErrorFields: map[string]string{}, ErrorString: "test"}},
		}

		proxy := ControlProxy{Client: mockClient{ValidateReply: reply}}
		errs := proxy.ValidateDeps([]core.RequestedMetric{}, []core.SubscribedPlugin{}, cdata.NewTree())
		So(errs, ShouldNotBeNil)
		So(len(errs), ShouldEqual, 1)
		Convey("So the error should resemble 'test'", func() {
			So(errs[0].Error(), ShouldResemble, "test")
		})

	})

	Convey("Control.ValidateDeps returns successfully", t, func() {
		reply := &rpc.ValidateDepsReply{}

		proxy := ControlProxy{Client: mockClient{ValidateReply: reply}}
		errs := proxy.ValidateDeps([]core.RequestedMetric{}, []core.SubscribedPlugin{}, cdata.NewTree())
		Convey("So the there should be no errors", func() {
			So(len(errs), ShouldEqual, 0)
		})

	})
}
Example #8
0
func TestQueuedJob(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	cdt := cdata.NewTree()
	Convey("Job()", t, func() {
		Convey("it should return the underlying job", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			qj := newQueuedJob(cj)
			So(qj.Job(), ShouldEqual, cj)
		})
	})
	Convey("Promise()", t, func() {
		Convey("it should return the underlying promise", func() {
			cj := newCollectorJob([]core.RequestedMetric{}, defaultDeadline, &mockCollector{}, cdt)
			qj := newQueuedJob(cj)
			So(qj.Promise().IsComplete(), ShouldBeFalse)
		})
	})
}
Example #9
0
// GetConfigTree converts config data for collection node in wmap into a proper cdata.ConfigDataTree
func (c *CollectWorkflowMapNode) GetConfigTree() (*cdata.ConfigDataTree, error) {
	cdt := cdata.NewTree()
	// Iterate over config and attempt to convert into data nodes in the tree
	for ns_, cmap := range c.Config {

		// Attempt to convert namespace string to proper namespace
		if !isValidNamespaceString(ns_) {
			return nil, errors.New(fmt.Sprintf("Invalid namespace: %v", ns_))
		}
		ns := strings.Split(ns_, "/")[1:]
		cdn, err := configtoConfigDataNode(cmap, ns_)
		if err != nil {
			return nil, err
		}
		cdt.Add(ns, cdn)
	}
	return cdt, nil
}
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)
		})
	})
}
func TestSubscriptionGroups_ProcessSpecifiedDynamicNegative(t *testing.T) {
	log.SetLevel(log.DebugLevel)
	c := New(getTestSGConfig())

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

	Convey("Loading a mock collector plugin", 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"
			mock1 := 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{mock1})
			<-lpe.sub
			So(len(sg.subscriptionMap), ShouldEqual, 1)
			group, ok := sg.subscriptionMap["task-id"]
			So(ok, ShouldBeTrue)
			So(group, ShouldNotBeNil)
			So(len(group.plugins), ShouldEqual, 1)
			So(subscribedPluginsContain(group.plugins, mock1), ShouldBeTrue)
			plgKey := key(group.plugins[0])
			So(group.metrics, ShouldContainKey, plgKey)
			metrics := group.metrics[plgKey].Metrics()
			// expected 1 subscribed metrics:`/intel/mock/host0/baz`
			So(len(metrics), ShouldEqual, 1)
			So(len(group.requestedMetrics), ShouldEqual, 1)
			So(metrics[0].Namespace().String(), ShouldEqual, group.requestedMetrics[0].Namespace().String())
			mts1 := len(metrics)

			Convey("loading another mock", func() {
				anotherMock1 := mockSubscribedPlugin{
					typeName: core.CollectorPluginType,
					name:     "anothermock",
					version:  1,
					config:   cdata.NewNode(),
				}
				_, err := loadPlg(c, helper.PluginFilePath("snap-plugin-collector-anothermock1"))
				So(err, ShouldBeNil)
				<-lpe.load
				serrs := sg.Process()
				So(len(serrs), ShouldEqual, 0)

				So(len(sg.subscriptionMap), ShouldEqual, 1)
				group, ok := sg.subscriptionMap["task-id"]
				So(ok, ShouldBeTrue)
				So(group, ShouldNotBeNil)
				So(len(group.plugins), ShouldEqual, 1)
				So(subscribedPluginsContain(group.plugins, mock1), ShouldBeTrue)
				So(subscribedPluginsContain(group.plugins, anotherMock1), ShouldBeFalse)
				plgKey := key(group.plugins[0])
				So(group.metrics, ShouldContainKey, plgKey)
				metrics := group.metrics[plgKey].Metrics()
				// expected 1 subscribed metrics:`/intel/mock/host0/baz`
				So(len(metrics), ShouldEqual, 1)
				So(len(group.requestedMetrics), ShouldEqual, 1)
				So(metrics[0].Namespace().String(), ShouldEqual, group.requestedMetrics[0].Namespace().String())
				mts2 := len(metrics)
				So(mts1, ShouldEqual, mts2)
			})
		})
	})
}
func TestSubscriptionGroups_ProcessDynamicPositive(t *testing.T) {
	log.SetLevel(log.DebugLevel)
	c := New(getTestSGConfig())

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

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

		<-lpe.load

		Convey("ValidateDeps", func() {
			requested := mockRequestedMetric{namespace: core.NewNamespace("intel").AddDynamicElement("wild", "wild description")}
			mock1 := mockSubscribedPlugin{
				typeName: core.CollectorPluginType,
				name:     "mock",
				version:  1,
				config:   cdata.NewNode(),
			}
			cnode := cdata.NewNode()
			cnode.AddItem("password", ctypes.ConfigValueStr{Value: "secret"})
			ctree := cdata.NewTree()
			ctree.Add([]string{"intel", "mock"}, cnode)
			sg := newSubscriptionGroups(c)
			So(sg, ShouldNotBeNil)
			errs := sg.ValidateDeps([]core.RequestedMetric{requested}, []core.SubscribedPlugin{mock1}, ctree)
			So(errs, ShouldBeNil)
			Convey("Subscription group created for requested metric with wildcards", func() {
				sg.Add("task-id", []core.RequestedMetric{requested}, ctree, []core.SubscribedPlugin{mock1})
				<-lpe.sub
				So(len(sg.subscriptionMap), ShouldEqual, 1)
				group, ok := sg.subscriptionMap["task-id"]
				So(ok, ShouldBeTrue)
				So(group, ShouldNotBeNil)
				So(len(group.plugins), ShouldEqual, 1)
				So(subscribedPluginsContain(group.plugins, mock1), ShouldBeTrue)
				plgKey := key(group.plugins[0])
				So(group.metrics, ShouldContainKey, plgKey)
				metrics := group.metrics[plgKey].Metrics()
				So(len(metrics), ShouldBeGreaterThan, 1)
				So(len(group.requestedMetrics), ShouldEqual, 1)
				mts1 := len(metrics)

				Convey("loading another mock", func() {
					anotherMock1 := mockSubscribedPlugin{
						typeName: core.CollectorPluginType,
						name:     "anothermock",
						version:  1,
						config:   cdata.NewNode(),
					}
					_, err := loadPlg(c, path.Join(helper.PluginFilePath("snap-plugin-collector-anothermock1")))
					So(err, ShouldBeNil)
					<-lpe.load
					serrs := sg.Process()
					So(len(serrs), ShouldEqual, 0)

					So(len(sg.subscriptionMap), ShouldEqual, 1)
					group, ok := sg.subscriptionMap["task-id"]
					So(ok, ShouldBeTrue)
					So(group, ShouldNotBeNil)
					So(len(group.plugins), ShouldEqual, 2)
					So(subscribedPluginsContain(group.plugins, mock1), ShouldBeTrue)
					So(subscribedPluginsContain(group.plugins, anotherMock1), ShouldBeTrue)
					plgKey1 := key(group.plugins[0])
					plgKey2 := key(group.plugins[1])
					So(group.metrics, ShouldContainKey, plgKey1)
					So(group.metrics, ShouldContainKey, plgKey2)
					metricsPlg1 := group.metrics[plgKey1].Metrics()
					metricsPlg2 := group.metrics[plgKey2].Metrics()
					So(len(metricsPlg1), ShouldBeGreaterThan, 1)
					So(len(metricsPlg2), ShouldBeGreaterThan, 1)
					So(len(group.requestedMetrics), ShouldEqual, 1)
					mts2 := len(metricsPlg1) + len(metricsPlg2)
					So(mts2, ShouldBeGreaterThan, mts1)
				})
			})
		})
	})
}
func TestSubscriptionGroups_ProcessStaticPositive(t *testing.T) {
	log.SetLevel(log.DebugLevel)
	c := New(getTestSGConfig())

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

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

		Convey("Subscription group created for requested metric with no wildcards", func() {
			requested := mockRequestedMetric{namespace: core.NewNamespace("intel", "mock", "foo")}
			mock1 := 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{mock1})
			<-lpe.sub
			So(len(sg.subscriptionMap), ShouldEqual, 1)
			group, ok := sg.subscriptionMap["task-id"]
			So(ok, ShouldBeTrue)
			So(group, ShouldNotBeNil)
			So(len(group.plugins), ShouldEqual, 1)
			So(subscribedPluginsContain(group.plugins, mock1), ShouldBeTrue)
			plgKey := key(group.plugins[0])
			So(group.metrics, ShouldContainKey, plgKey)
			metrics := group.metrics[plgKey].Metrics()
			So(len(metrics), ShouldEqual, 1)
			So(len(group.requestedMetrics), ShouldEqual, 1)
			So(metrics[0].Namespace().String(), ShouldEqual, group.requestedMetrics[0].Namespace().String())

			Convey("loading another mock", func() {
				mock2 := mockSubscribedPlugin{
					typeName: core.CollectorPluginType,
					name:     "mock",
					version:  2,
					config:   cdata.NewNode(),
				}
				_, err := loadPlg(c, helper.PluginFilePath("snap-plugin-collector-mock2"))
				So(err, ShouldBeNil)
				<-lpe.load
				serrs := sg.Process()
				So(len(serrs), ShouldEqual, 0)

				So(len(sg.subscriptionMap), ShouldEqual, 1)
				group, ok := sg.subscriptionMap["task-id"]
				So(ok, ShouldBeTrue)
				So(group, ShouldNotBeNil)
				So(len(group.plugins), ShouldEqual, 1)
				So(subscribedPluginsContain(group.plugins, mock1), ShouldBeFalse)
				So(subscribedPluginsContain(group.plugins, mock2), ShouldBeTrue)
				plgKey := key(group.plugins[0])
				So(group.metrics, ShouldContainKey, plgKey)
				metrics := group.metrics[plgKey].Metrics()
				So(len(metrics), ShouldEqual, 1)
				So(len(group.requestedMetrics), ShouldEqual, 1)
				So(metrics[0].Namespace().String(), ShouldEqual, group.requestedMetrics[0].Namespace().String())
			})
		})
	})
}