// New returns snap-plugin-collector-iostat instance
func New() (*IOSTAT, error) {
	iostat := &IOSTAT{
		cmd:    command.New(),
		parser: parser.New(),
	}
	return iostat, nil
}
func TestIostat(t *testing.T) {
	iostat := &IOSTAT{parser: parser.New(), cmd: &mockCmdRunner{}}

	Convey("Given invalid metric namespace collect metrics", t, func() {
		badMetrics := []plugin.PluginMetricType{
			plugin.PluginMetricType{
				Namespace_: []string{"intel", "linux", "iostat", "device", "sda", "bad"},
			},
		}
		So(func() { iostat.CollectMetrics(badMetrics) }, ShouldNotPanic)
		result, err := iostat.CollectMetrics(badMetrics)
		So(len(result), ShouldEqual, len(badMetrics))
		So(err, ShouldBeNil)

		for _, r := range result {
			So(r.Namespace(), ShouldBeEmpty)
			So(r.Data(), ShouldBeNil)
			So(r.Source(), ShouldBeEmpty)
		}
	})

	Convey("Given valid metric namespace collect metrics", t, func() {
		So(func() { iostat.CollectMetrics(mockMts) }, ShouldNotPanic)
		result, err := iostat.CollectMetrics(mockMts)
		So(len(result), ShouldEqual, len(mockMts))
		So(err, ShouldBeNil)
		So(result[0].Data(), ShouldEqual, 0)
		So(result[1].Data(), ShouldEqual, 0)
		So(result[2].Data(), ShouldEqual, 0)
		So(result[3].Data(), ShouldEqual, 0.01)
		So(result[4].Data(), ShouldEqual, 15.34)
	})

	Convey("Get metric types", t, func() {
		mts, err := iostat.GetMetricTypes(plugin.PluginConfigType{})
		So(err, ShouldBeNil)
		So(len(mts), ShouldEqual, 123)
	})

	Convey("Get config policy", t, func() {
		policy, err := iostat.GetConfigPolicy()
		So(err, ShouldBeNil)
		So(policy, ShouldResemble, cpolicy.New())
	})
}
func TestIostat(t *testing.T) {
	iostat := &IOSTAT{parser: parser.New(), cmd: &mockCmdRunner{}}

	Convey("Given invalid metric namespace collect metrics", t, func() {
		badMetrics := []plugin.MetricType{
			plugin.MetricType{
				Namespace_: core.NewNamespace("intel", "linux", "iostat", "device", "sda", "bad"),
			},
		}
		So(func() { iostat.CollectMetrics(badMetrics) }, ShouldNotPanic)
		result, err := iostat.CollectMetrics(badMetrics)
		So(err, ShouldBeNil)

		for _, r := range result {
			So(r.Namespace(), ShouldBeEmpty)
			So(r.Data(), ShouldBeNil)
		}
	})

	Convey("Given valid static metric namespace collect metrics", t, func() {
		So(func() { iostat.CollectMetrics(staticMockMts) }, ShouldNotPanic)
		result, err := iostat.CollectMetrics(staticMockMts)
		So(len(result), ShouldEqual, 6)
		So(err, ShouldBeNil)
		So(result[0].Data(), ShouldEqual, 0.50)
		So(result[1].Data(), ShouldEqual, 0)
		So(result[2].Data(), ShouldEqual, 0.13)
		So(result[3].Data(), ShouldEqual, 0)
		So(result[4].Data(), ShouldEqual, 0)
		So(result[5].Data(), ShouldEqual, 99.37)
	})

	Convey("Given valid dynamic metric namespace collect metrics", t, func() {
		So(func() { iostat.CollectMetrics(dynamicMockMts) }, ShouldNotPanic)
		result, err := iostat.CollectMetrics(dynamicMockMts)
		So(len(result), ShouldEqual, 72)
		So(err, ShouldBeNil)

		m := make(map[string]interface{}, len(result))
		for _, r := range result {
			m[r.Namespace().String()] = r.Data()
		}

		So(len(m), ShouldEqual, len(refMap))
		for key, val := range refMap {
			v, ok := m[key]
			So(ok, ShouldBeTrue)
			So(v, ShouldEqual, val)
		}

		for _, r := range result {
			_, ok := r.Data_.(float64)
			So(ok, ShouldBeTrue)
		}
	})

	Convey("Get metric types", t, func() {
		mts, err := iostat.GetMetricTypes(plugin.ConfigType{})
		So(err, ShouldBeNil)
		So(len(mts), ShouldEqual, 19)

		namespaces := []string{}
		for _, m := range mts {
			namespaces = append(namespaces, m.Namespace().String())
		}

		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%idle")
		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%iowait")
		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%nice")
		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%steal")
		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%system")
		So(namespaces, ShouldContain, "/intel/linux/iostat/avg-cpu/%user")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/%util")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/avgqu-sz")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/avgrq-sz")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/await")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/r_await")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/r_per_sec")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/rkB_per_sec")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/rrqm_per_sec")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/svctm")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/w_await")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/w_per_sec")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/wkB_per_sec")
		So(namespaces, ShouldContain, "/intel/linux/iostat/device/*/wrqm_per_sec")
	})

	Convey("Get config policy", t, func() {
		policy, err := iostat.GetConfigPolicy()
		So(err, ShouldBeNil)
		So(policy, ShouldResemble, cpolicy.New())
	})
}