<commit_before>package system

import (
	"encoding/json"
	"testing"
	"time"

	"github.com/influxdata/telegraf/testutil"

	"github.com/fsouza/go-dockerclient"
	"github.com/stretchr/testify/require"
)

func TestDockerGatherContainerStats(t *testing.T) {
	var acc testutil.Accumulator
	stats := testStats()

	tags := map[string]string{
		"cont_id":    "foobarbaz",
		"cont_name":  "redis",
		"cont_image": "redis/image",
	}
	gatherContainerStats(stats, &acc, tags)

	// test docker_net measurement
	netfields := map[string]interface{}{
		"rx_dropped": uint64(1),
		"rx_bytes":   uint64(2),
		"rx_errors":  uint64(3),
		"tx_packets": uint64(4),
		"tx_dropped": uint64(1),
		"rx_packets": uint64(2),
		"tx_errors":  uint64(3),
		"tx_bytes":   uint64(4),
	}
	nettags := copyTags(tags)
	nettags["network"] = "eth0"
	acc.AssertContainsTaggedFields(t, "docker_net", netfields, nettags)

	// test docker_blkio measurement
	blkiotags := copyTags(tags)
	blkiotags["device"] = "6:0"
	blkiofields := map[string]interface{}{
		"io_service_bytes_recursive_read": uint64(100),
		"io_serviced_recursive_write":     uint64(101),
	}
	acc.AssertContainsTaggedFields(t, "docker_blkio", blkiofields, blkiotags)

	// test docker_mem measurement
	memfields := map[string]interface{}{
		"max_usage":                 uint64(1001),
		"usage":                     uint64(1111),
		"fail_count":                uint64(1),
		"limit":                     uint64(2000),
		"total_pgmafault":           uint64(0),
		"cache":                     uint64(0),
		"mapped_file":               uint64(0),
		"total_inactive_file":       uint64(0),
		"pgpgout":                   uint64(0),
		"rss":                       uint64(0),
		"total_mapped_file":         uint64(0),
		"writeback":                 uint64(0),
		"unevictable":               uint64(0),
		"pgpgin":                    uint64(0),
		"total_unevictable":         uint64(0),
		"pgmajfault":                uint64(0),
		"total_rss":                 uint64(44),
		"total_rss_huge":            uint64(444),
		"total_writeback":           uint64(55),
		"total_inactive_anon":       uint64(0),
		"rss_huge":                  uint64(0),
		"hierarchical_memory_limit": uint64(0),
		"total_pgfault":             uint64(0),
		"total_active_file":         uint64(0),
		"active_anon":               uint64(0),
		"total_active_anon":         uint64(0),
		"total_pgpgout":             uint64(0),
		"total_cache":               uint64(0),
		"inactive_anon":             uint64(0),
		"active_file":               uint64(1),
		"pgfault":                   uint64(2),
		"inactive_file":             uint64(3),
		"total_pgpgin":              uint64(4),
		"usage_percent":             float64(55.55),
	}

	acc.AssertContainsTaggedFields(t, "docker_mem", memfields, tags)

	// test docker_cpu measurement
	cputags := copyTags(tags)
	cputags["cpu"] = "cpu-total"
	cpufields := map[string]interface{}{
		"usage_total":                  uint64(500),
		"usage_in_usermode":            uint64(100),
		"usage_in_kernelmode":          uint64(200),
		"usage_system":                 uint64(100),
		"throttling_periods":           uint64(1),
		"throttling_throttled_periods": uint64(0),
		"throttling_throttled_time":    uint64(0),
		"usage_percent":                float64(400.0),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpufields, cputags)

	cputags["cpu"] = "cpu0"
	cpu0fields := map[string]interface{}{
		"usage_total": uint64(1),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu0fields, cputags)

	cputags["cpu"] = "cpu1"
	cpu1fields := map[string]interface{}{
		"usage_total": uint64(1002),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu1fields, cputags)
}

func testStats() *docker.Stats {
	stats := &docker.Stats{
		Read:     time.Now(),
		Networks: make(map[string]docker.NetworkStats),
	}

	stats.CPUStats.CPUUsage.PercpuUsage = []uint64{1, 1002}
	stats.CPUStats.CPUUsage.UsageInUsermode = 100
	stats.CPUStats.CPUUsage.TotalUsage = 500
	stats.CPUStats.CPUUsage.UsageInKernelmode = 200
	stats.CPUStats.SystemCPUUsage = 100
	stats.CPUStats.ThrottlingData.Periods = 1

	stats.PreCPUStats.CPUUsage.TotalUsage = 400
	stats.PreCPUStats.SystemCPUUsage = 50

	stats.MemoryStats.Stats.TotalPgmafault = 0
	stats.MemoryStats.Stats.Cache = 0
	stats.MemoryStats.Stats.MappedFile = 0
	stats.MemoryStats.Stats.TotalInactiveFile = 0
	stats.MemoryStats.Stats.Pgpgout = 0
	stats.MemoryStats.Stats.Rss = 0
	stats.MemoryStats.Stats.TotalMappedFile = 0
	stats.MemoryStats.Stats.Writeback = 0
	stats.MemoryStats.Stats.Unevictable = 0
	stats.MemoryStats.Stats.Pgpgin = 0
	stats.MemoryStats.Stats.TotalUnevictable = 0
	stats.MemoryStats.Stats.Pgmajfault = 0
	stats.MemoryStats.Stats.TotalRss = 44
	stats.MemoryStats.Stats.TotalRssHuge = 444
	stats.MemoryStats.Stats.TotalWriteback = 55
	stats.MemoryStats.Stats.TotalInactiveAnon = 0
	stats.MemoryStats.Stats.RssHuge = 0
	stats.MemoryStats.Stats.HierarchicalMemoryLimit = 0
	stats.MemoryStats.Stats.TotalPgfault = 0
	stats.MemoryStats.Stats.TotalActiveFile = 0
	stats.MemoryStats.Stats.ActiveAnon = 0
	stats.MemoryStats.Stats.TotalActiveAnon = 0
	stats.MemoryStats.Stats.TotalPgpgout = 0
	stats.MemoryStats.Stats.TotalCache = 0
	stats.MemoryStats.Stats.InactiveAnon = 0
	stats.MemoryStats.Stats.ActiveFile = 1
	stats.MemoryStats.Stats.Pgfault = 2
	stats.MemoryStats.Stats.InactiveFile = 3
	stats.MemoryStats.Stats.TotalPgpgin = 4

	stats.MemoryStats.MaxUsage = 1001
	stats.MemoryStats.Usage = 1111
	stats.MemoryStats.Failcnt = 1
	stats.MemoryStats.Limit = 2000

	stats.Networks["eth0"] = docker.NetworkStats{
		RxDropped: 1,
		RxBytes:   2,
		RxErrors:  3,
		TxPackets: 4,
		TxDropped: 1,
		RxPackets: 2,
		TxErrors:  3,
		TxBytes:   4,
	}

	sbr := docker.BlkioStatsEntry{
		Major: 6,
		Minor: 0,
		Op:    "read",
		Value: 100,
	}
	sr := docker.BlkioStatsEntry{
		Major: 6,
		Minor: 0,
		Op:    "write",
		Value: 101,
	}

	stats.BlkioStats.IOServiceBytesRecursive = append(
		stats.BlkioStats.IOServiceBytesRecursive, sbr)
	stats.BlkioStats.IOServicedRecursive = append(
		stats.BlkioStats.IOServicedRecursive, sr)

	return stats
}

type FakeDockerClient struct {
}

func (d FakeDockerClient) Info() (*docker.Env, error) {
	env := docker.Env{"Containers=108", "OomKillDisable=false", "SystemTime=2016-02-24T00:55:09.15073105-05:00", "NEventsListener=0", "ID=5WQQ:TFWR:FDNG:OKQ3:37Y4:FJWG:QIKK:623T:R3ME:QTKB:A7F7:OLHD", "Debug=false", "LoggingDriver=json-file", "KernelVersion=4.3.0-1-amd64", "IndexServerAddress=https://index.docker.io/v1/", "MemTotal=3840757760", "Images=199", "CpuCfsQuota=true", "Name=absol", "SwapLimit=false", "IPv4Forwarding=true", "ExecutionDriver=native-0.2", "InitSha1=23a51f3c916d2b5a3bbb31caf301fd2d14edd518", "ExperimentalBuild=false", "CpuCfsPeriod=true", "RegistryConfig={\"IndexConfigs\":{\"docker.io\":{\"Mirrors\":null,\"Name\":\"docker.io\",\"Official\":true,\"Secure\":true}},\"InsecureRegistryCIDRs\":[\"127.0.0.0/8\"],\"Mirrors\":null}", "OperatingSystem=Linux Mint LMDE (containerized)", "BridgeNfIptables=true", "HttpsProxy=", "Labels=null", "MemoryLimit=false", "DriverStatus=[[\"Pool Name\",\"docker-8:1-1182287-pool\"],[\"Pool Blocksize\",\"65.54 kB\"],[\"Backing Filesystem\",\"extfs\"],[\"Data file\",\"/dev/loop0\"],[\"Metadata file\",\"/dev/loop1\"],[\"Data Space Used\",\"17.3 GB\"],[\"Data Space Total\",\"107.4 GB\"],[\"Data Space Available\",\"36.53 GB\"],[\"Metadata Space Used\",\"20.97 MB\"],[\"Metadata Space Total\",\"2.147 GB\"],[\"Metadata Space Available\",\"2.127 GB\"],[\"Udev Sync Supported\",\"true\"],[\"Deferred Removal Enabled\",\"false\"],[\"Data loop file\",\"/var/lib/docker/devicemapper/devicemapper/data\"],[\"Metadata loop file\",\"/var/lib/docker/devicemapper/devicemapper/metadata\"],[\"Library Version\",\"1.02.115 (2016-01-25)\"]]", "NFd=19", "HttpProxy=", "Driver=devicemapper", "NGoroutines=39", "InitPath=/usr/lib/docker.io/dockerinit", "NCPU=4", "DockerRootDir=/var/lib/docker", "NoProxy=", "BridgeNfIp6tables=true"}
	return &env, nil
}

func (d FakeDockerClient) ListContainers(opts docker.ListContainersOptions) ([]docker.APIContainers, error) {
	container1 := docker.APIContainers{
		ID:      "e2173b9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296b7dfb",
		Image:   "quay.io/coreos/etcd:v2.2.2",
		Command: "/etcd -name etcd0 -advertise-client-urls http://localhost:2379 -listen-client-urls http://0.0.0.0:2379",
		Created: 1455941930,
		Status:  "Up 4 hours",
		Ports: []docker.APIPort{
			docker.APIPort{
				PrivatePort: 7001,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 4001,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 2380,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 2379,
				PublicPort:  2379,
				Type:        "tcp",
				IP:          "0.0.0.0",
			},
		},
		SizeRw:     0,
		SizeRootFs: 0,
		Names:      []string{"/etcd"},
	}
	container2 := docker.APIContainers{
		ID:      "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
		Image:   "quay.io/coreos/etcd:v2.2.2",
		Command: "/etcd -name etcd2 -advertise-client-urls http://localhost:2379 -listen-client-urls http://0.0.0.0:2379",
		Created: 1455941933,
		Status:  "Up 4 hours",
		Ports: []docker.APIPort{
			docker.APIPort{
				PrivatePort: 7002,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 4002,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 2381,
				PublicPort:  0,
				Type:        "tcp",
			},
			docker.APIPort{
				PrivatePort: 2382,
				PublicPort:  2382,
				Type:        "tcp",
				IP:          "0.0.0.0",
			},
		},
		SizeRw:     0,
		SizeRootFs: 0,
		Names:      []string{"/etcd2"},
	}

	containers := []docker.APIContainers{container1, container2}
	return containers, nil

	//#{e6a96c84ca91a5258b7cb752579fb68826b68b49ff957487695cd4d13c343b44 titilambert/snmpsim /bin/sh -c 'snmpsimd --agent-udpv4-endpoint=0.0.0.0:31161 --process-user=root --process-group=user' 1455724831 Up 4 hours [{31161 31161 udp 0.0.0.0}] 0 0 [/snmp] map[]}]2016/02/24 01:05:01 Gathered metrics, (3s interval), from 1 inputs in 1.233836656s
}

func (d FakeDockerClient) Stats(opts docker.StatsOptions) error {
	jsonStat := `{"read":"2016-02-24T11:42:27.472459608-05:00","memory_stats":{"stats":{},"limit":18935443456},"blkio_stats":{"io_service_bytes_recursive":[{"major":252,"minor":1,"op":"Read","value":753664},{"major":252,"minor":1,"op":"Write"},{"major":252,"minor":1,"op":"Sync"},{"major":252,"minor":1,"op":"Async","value":753664},{"major":252,"minor":1,"op":"Total","value":753664}],"io_serviced_recursive":[{"major":252,"minor":1,"op":"Read","value":26},{"major":252,"minor":1,"op":"Write"},{"major":252,"minor":1,"op":"Sync"},{"major":252,"minor":1,"op":"Async","value":26},{"major":252,"minor":1,"op":"Total","value":26}]},"cpu_stats":{"cpu_usage":{"percpu_usage":[17871,4959158,1646137,1231652,11829401,244656,369972,0],"usage_in_usermode":10000000,"total_usage":20298847},"system_cpu_usage":24052607520000000,"throttling_data":{}},"precpu_stats":{"cpu_usage":{"percpu_usage":[17871,4959158,1646137,1231652,11829401,244656,369972,0],"usage_in_usermode":10000000,"total_usage":20298847},"system_cpu_usage":24052599550000000,"throttling_data":{}}}`
	var stat docker.Stats
	json.Unmarshal([]byte(jsonStat), &stat)
	opts.Stats <- &stat
	return nil
}

func TestDockerGatherInfo(t *testing.T) {
	var acc testutil.Accumulator
	client := FakeDockerClient{}
	d := Docker{client: client}

	err := d.Gather(&acc)

	require.NoError(t, err)

	acc.AssertContainsTaggedFields(t,
		"docker",
		map[string]interface{}{
			"n_listener_events":       int64(0),
			"n_cpus":                  int64(4),
			"n_used_file_descriptors": int64(19),
			"n_containers":            int64(108),
			"n_images":                int64(199),
			"n_goroutines":            int64(39),
		},
		map[string]string{},
	)

	acc.AssertContainsTaggedFields(t,
		"docker_data",
		map[string]interface{}{
			"used":      int64(17300000000),
			"total":     int64(107400000000),
			"available": int64(36530000000),
		},
		map[string]string{
			"unit": "bytes",
		},
	)
	acc.AssertContainsTaggedFields(t,
		"docker_cpu",
		map[string]interface{}{
			"usage_total": uint64(1231652),
		},
		map[string]string{
			"cont_id":    "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
			"cont_name":  "etcd2",
			"cont_image": "quay.io/coreos/etcd:v2.2.2",
			"cpu":        "cpu3",
		},
	)
	acc.AssertContainsTaggedFields(t,
		"docker_mem",
		map[string]interface{}{
			"total_pgpgout":             uint64(0),
			"usage_percent":             float64(0),
			"rss":                       uint64(0),
			"total_writeback":           uint64(0),
			"active_anon":               uint64(0),
			"total_pgmafault":           uint64(0),
			"total_rss":                 uint64(0),
			"total_unevictable":         uint64(0),
			"active_file":               uint64(0),
			"total_mapped_file":         uint64(0),
			"pgpgin":                    uint64(0),
			"total_active_file":         uint64(0),
			"total_active_anon":         uint64(0),
			"total_cache":               uint64(0),
			"inactive_anon":             uint64(0),
			"pgmajfault":                uint64(0),
			"total_inactive_anon":       uint64(0),
			"total_rss_huge":            uint64(0),
			"rss_huge":                  uint64(0),
			"hierarchical_memory_limit": uint64(0),
			"pgpgout":                   uint64(0),
			"unevictable":               uint64(0),
			"total_inactive_file":       uint64(0),
			"writeback":                 uint64(0),
			"total_pgfault":             uint64(0),
			"total_pgpgin":              uint64(0),
			"cache":                     uint64(0),
			"mapped_file":               uint64(0),
			"inactive_file":             uint64(0),
			"max_usage":                 uint64(0),
			"fail_count":                uint64(0),
			"pgfault":                   uint64(0),
			"usage":                     uint64(0),
			"limit":                     uint64(18935443456),
		},
		map[string]string{
			"cont_id":    "<KEY>",
			"cont_name":  "etcd2",
			"cont_image": "quay.io/coreos/etcd:v2.2.2",
		},
	)

	//fmt.Print(info)
}
<commit_msg>input(docker): Fixed tests to work with engine-api<commit_after>package system

import (
	"io"
	"io/ioutil"
	"strings"
	"testing"
	"time"

	"golang.org/x/net/context"

	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/registry"
	"github.com/influxdata/telegraf/testutil"

	"github.com/stretchr/testify/require"
)

func TestDockerGatherContainerStats(t *testing.T) {
	var acc testutil.Accumulator
	stats := testStats()

	tags := map[string]string{
		"cont_id":    "foobarbaz",
		"cont_name":  "redis",
		"cont_image": "redis/image",
	}
	gatherContainerStats(stats, &acc, tags)

	// test docker_net measurement
	netfields := map[string]interface{}{
		"rx_dropped": uint64(1),
		"rx_bytes":   uint64(2),
		"rx_errors":  uint64(3),
		"tx_packets": uint64(4),
		"tx_dropped": uint64(1),
		"rx_packets": uint64(2),
		"tx_errors":  uint64(3),
		"tx_bytes":   uint64(4),
	}
	nettags := copyTags(tags)
	nettags["network"] = "eth0"
	acc.AssertContainsTaggedFields(t, "docker_net", netfields, nettags)

	// test docker_blkio measurement
	blkiotags := copyTags(tags)
	blkiotags["device"] = "6:0"
	blkiofields := map[string]interface{}{
		"io_service_bytes_recursive_read": uint64(100),
		"io_serviced_recursive_write":     uint64(101),
	}
	acc.AssertContainsTaggedFields(t, "docker_blkio", blkiofields, blkiotags)

	// test docker_mem measurement
	memfields := map[string]interface{}{
		"max_usage":                 uint64(1001),
		"usage":                     uint64(1111),
		"fail_count":                uint64(1),
		"limit":                     uint64(2000),
		"total_pgmafault":           uint64(0),
		"cache":                     uint64(0),
		"mapped_file":               uint64(0),
		"total_inactive_file":       uint64(0),
		"pgpgout":                   uint64(0),
		"rss":                       uint64(0),
		"total_mapped_file":         uint64(0),
		"writeback":                 uint64(0),
		"unevictable":               uint64(0),
		"pgpgin":                    uint64(0),
		"total_unevictable":         uint64(0),
		"pgmajfault":                uint64(0),
		"total_rss":                 uint64(44),
		"total_rss_huge":            uint64(444),
		"total_writeback":           uint64(55),
		"total_inactive_anon":       uint64(0),
		"rss_huge":                  uint64(0),
		"hierarchical_memory_limit": uint64(0),
		"total_pgfault":             uint64(0),
		"total_active_file":         uint64(0),
		"active_anon":               uint64(0),
		"total_active_anon":         uint64(0),
		"total_pgpgout":             uint64(0),
		"total_cache":               uint64(0),
		"inactive_anon":             uint64(0),
		"active_file":               uint64(1),
		"pgfault":                   uint64(2),
		"inactive_file":             uint64(3),
		"total_pgpgin":              uint64(4),
		"usage_percent":             float64(55.55),
	}

	acc.AssertContainsTaggedFields(t, "docker_mem", memfields, tags)

	// test docker_cpu measurement
	cputags := copyTags(tags)
	cputags["cpu"] = "cpu-total"
	cpufields := map[string]interface{}{
		"usage_total":                  uint64(500),
		"usage_in_usermode":            uint64(100),
		"usage_in_kernelmode":          uint64(200),
		"usage_system":                 uint64(100),
		"throttling_periods":           uint64(1),
		"throttling_throttled_periods": uint64(0),
		"throttling_throttled_time":    uint64(0),
		"usage_percent":                float64(400.0),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpufields, cputags)

	cputags["cpu"] = "cpu0"
	cpu0fields := map[string]interface{}{
		"usage_total": uint64(1),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu0fields, cputags)

	cputags["cpu"] = "cpu1"
	cpu1fields := map[string]interface{}{
		"usage_total": uint64(1002),
	}
	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu1fields, cputags)
}

func testStats() *types.StatsJSON {
	stats := &types.StatsJSON{}
	stats.Read = time.Now()
	stats.Networks = make(map[string]types.NetworkStats)

	stats.CPUStats.CPUUsage.PercpuUsage = []uint64{1, 1002}
	stats.CPUStats.CPUUsage.UsageInUsermode = 100
	stats.CPUStats.CPUUsage.TotalUsage = 500
	stats.CPUStats.CPUUsage.UsageInKernelmode = 200
	stats.CPUStats.SystemUsage = 100
	stats.CPUStats.ThrottlingData.Periods = 1

	stats.PreCPUStats.CPUUsage.TotalUsage = 400
	stats.PreCPUStats.SystemUsage = 50

	stats.MemoryStats.Stats = make(map[string]uint64)
	stats.MemoryStats.Stats["total_pgmajfault"] = 0
	stats.MemoryStats.Stats["cache"] = 0
	stats.MemoryStats.Stats["mapped_file"] = 0
	stats.MemoryStats.Stats["total_inactive_file"] = 0
	stats.MemoryStats.Stats["pagpgout"] = 0
	stats.MemoryStats.Stats["rss"] = 0
	stats.MemoryStats.Stats["total_mapped_file"] = 0
	stats.MemoryStats.Stats["writeback"] = 0
	stats.MemoryStats.Stats["unevictable"] = 0
	stats.MemoryStats.Stats["pgpgin"] = 0
	stats.MemoryStats.Stats["total_unevictable"] = 0
	stats.MemoryStats.Stats["pgmajfault"] = 0
	stats.MemoryStats.Stats["total_rss"] = 44
	stats.MemoryStats.Stats["total_rss_huge"] = 444
	stats.MemoryStats.Stats["total_write_back"] = 55
	stats.MemoryStats.Stats["total_inactive_anon"] = 0
	stats.MemoryStats.Stats["rss_huge"] = 0
	stats.MemoryStats.Stats["hierarchical_memory_limit"] = 0
	stats.MemoryStats.Stats["total_pgfault"] = 0
	stats.MemoryStats.Stats["total_active_file"] = 0
	stats.MemoryStats.Stats["active_anon"] = 0
	stats.MemoryStats.Stats["total_active_anon"] = 0
	stats.MemoryStats.Stats["total_pgpgout"] = 0
	stats.MemoryStats.Stats["total_cache"] = 0
	stats.MemoryStats.Stats["inactive_anon"] = 0
	stats.MemoryStats.Stats["active_file"] = 1
	stats.MemoryStats.Stats["pgfault"] = 2
	stats.MemoryStats.Stats["inactive_file"] = 3
	stats.MemoryStats.Stats["total_pgpgin"] = 4

	stats.MemoryStats.MaxUsage = 1001
	stats.MemoryStats.Usage = 1111
	stats.MemoryStats.Failcnt = 1
	stats.MemoryStats.Limit = 2000

	stats.Networks["eth0"] = types.NetworkStats{
		RxDropped: 1,
		RxBytes:   2,
		RxErrors:  3,
		TxPackets: 4,
		TxDropped: 1,
		RxPackets: 2,
		TxErrors:  3,
		TxBytes:   4,
	}

	sbr := types.BlkioStatEntry{
		Major: 6,
		Minor: 0,
		Op:    "read",
		Value: 100,
	}
	sr := types.BlkioStatEntry{
		Major: 6,
		Minor: 0,
		Op:    "write",
		Value: 101,
	}

	stats.BlkioStats.IoServiceBytesRecursive = append(
		stats.BlkioStats.IoServiceBytesRecursive, sbr)
	stats.BlkioStats.IoServicedRecursive = append(
		stats.BlkioStats.IoServicedRecursive, sr)

	return stats
}

type FakeDockerClient struct {
}

func (d FakeDockerClient) Info(ctx context.Context) (types.Info, error) {
	env := types.Info{
		Containers:         108,
		OomKillDisable:     false,
		SystemTime:         "2016-02-24T00:55:09.15073105-05:00",
		NEventsListener:    0,
		ID:                 "5WQQ:TFWR:FDNG:OKQ3:37Y4:FJWG:QIKK:623T:R3ME:QTKB:A7F7:OLHD",
		Debug:              false,
		LoggingDriver:      "json-file",
		KernelVersion:      "4.3.0-1-amd64",
		IndexServerAddress: "https://index.docker.io/v1/",
		MemTotal:           3840757760,
		Images:             199,
		CPUCfsQuota:        true,
		Name:               "absol",
		SwapLimit:          false,
		IPv4Forwarding:     true,
		ExecutionDriver:    "native-0.2",
		ExperimentalBuild:  false,
		CPUCfsPeriod:       true,
		RegistryConfig: &registry.ServiceConfig{
			IndexConfigs: map[string]*registry.IndexInfo{
				"docker.io": {
					Name:     "docker.io",
					Mirrors:  []string{},
					Official: true,
					Secure:   true,
				},
			}, InsecureRegistryCIDRs: []*registry.NetIPNet{{IP: []byte{127, 0, 0, 0}, Mask: []byte{255, 0, 0, 0}}}, Mirrors: []string{}},
		OperatingSystem:   "Linux Mint LMDE (containerized)",
		BridgeNfIptables:  true,
		HTTPSProxy:        "",
		Labels:            []string{},
		MemoryLimit:       false,
		DriverStatus:      [][2]string{{"Pool Name", "docker-8:1-1182287-pool"}, {"Pool Blocksize", "65.54 kB"}, {"Backing Filesystem", "extfs"}, {"Data file", "/dev/loop0"}, {"Metadata file", "/dev/loop1"}, {"Data Space Used", "17.3 GB"}, {"Data Space Total", "107.4 GB"}, {"Data Space Available", "36.53 GB"}, {"Metadata Space Used", "20.97 MB"}, {"Metadata Space Total", "2.147 GB"}, {"Metadata Space Available", "2.127 GB"}, {"Udev Sync Supported", "true"}, {"Deferred Removal Enabled", "false"}, {"Data loop file", "/var/lib/docker/devicemapper/devicemapper/data"}, {"Metadata loop file", "/var/lib/docker/devicemapper/devicemapper/metadata"}, {"Library Version", "1.02.115 (2016-01-25)"}},
		NFd:               19,
		HTTPProxy:         "",
		Driver:            "devicemapper",
		NGoroutines:       39,
		NCPU:              4,
		DockerRootDir:     "/var/lib/docker",
		NoProxy:           "",
		BridgeNfIP6tables: true,
	}
	return env, nil
}

func (d FakeDockerClient) ContainerList(octx context.Context, options types.ContainerListOptions) ([]types.Container, error) {
	container1 := types.Container{
		ID:      "e2173b9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296b7dfb",
		Names:   []string{"/etcd"},
		Image:   "quay.io/coreos/etcd:v2.2.2",
		Command: "/etcd -name etcd0 -advertise-client-urls http://localhost:2379 -listen-client-urls http://0.0.0.0:2379",
		Created: 1455941930,
		Status:  "Up 4 hours",
		Ports: []types.Port{
			types.Port{
				PrivatePort: 7001,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 4001,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 2380,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 2379,
				PublicPort:  2379,
				Type:        "tcp",
				IP:          "0.0.0.0",
			},
		},
		SizeRw:     0,
		SizeRootFs: 0,
	}
	container2 := types.Container{
		ID:      "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
		Names:   []string{"/etcd2"},
		Image:   "quay.io/coreos/etcd:v2.2.2",
		Command: "/etcd -name etcd2 -advertise-client-urls http://localhost:2379 -listen-client-urls http://0.0.0.0:2379",
		Created: 1455941933,
		Status:  "Up 4 hours",
		Ports: []types.Port{
			types.Port{
				PrivatePort: 7002,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 4002,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 2381,
				PublicPort:  0,
				Type:        "tcp",
			},
			types.Port{
				PrivatePort: 2382,
				PublicPort:  2382,
				Type:        "tcp",
				IP:          "0.0.0.0",
			},
		},
		SizeRw:     0,
		SizeRootFs: 0,
	}

	containers := []types.Container{container1, container2}
	return containers, nil

	//#{e6a96c84ca91a5258b7cb752579fb68826b68b49ff957487695cd4d13c343b44 titilambert/snmpsim /bin/sh -c 'snmpsimd --agent-udpv4-endpoint=0.0.0.0:31161 --process-user=root --process-group=user' 1455724831 Up 4 hours [{31161 31161 udp 0.0.0.0}] 0 0 [/snmp] map[]}]2016/02/24 01:05:01 Gathered metrics, (3s interval), from 1 inputs in 1.233836656s
}

func (d FakeDockerClient) ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error) {
	var stat io.ReadCloser
	jsonStat := `{"read":"2016-02-24T11:42:27.472459608-05:00","memory_stats":{"stats":{},"limit":18935443456},"blkio_stats":{"io_service_bytes_recursive":[{"major":252,"minor":1,"op":"Read","value":753664},{"major":252,"minor":1,"op":"Write"},{"major":252,"minor":1,"op":"Sync"},{"major":252,"minor":1,"op":"Async","value":753664},{"major":252,"minor":1,"op":"Total","value":753664}],"io_serviced_recursive":[{"major":252,"minor":1,"op":"Read","value":26},{"major":252,"minor":1,"op":"Write"},{"major":252,"minor":1,"op":"Sync"},{"major":252,"minor":1,"op":"Async","value":26},{"major":252,"minor":1,"op":"Total","value":26}]},"cpu_stats":{"cpu_usage":{"percpu_usage":[17871,4959158,1646137,1231652,11829401,244656,369972,0],"usage_in_usermode":10000000,"total_usage":20298847},"system_cpu_usage":24052607520000000,"throttling_data":{}},"precpu_stats":{"cpu_usage":{"percpu_usage":[17871,4959158,1646137,1231652,11829401,244656,369972,0],"usage_in_usermode":10000000,"total_usage":20298847},"system_cpu_usage":24052599550000000,"throttling_data":{}}}`
	stat = ioutil.NopCloser(strings.NewReader(jsonStat))
	return stat, nil
}

func TestDockerGatherInfo(t *testing.T) {
	var acc testutil.Accumulator
	client := FakeDockerClient{}
	d := Docker{client: client}

	err := d.Gather(&acc)

	require.NoError(t, err)

	acc.AssertContainsTaggedFields(t,
		"docker",
		map[string]interface{}{
			"n_listener_events":       int(0),
			"n_cpus":                  int(4),
			"n_used_file_descriptors": int(19),
			"n_containers":            int(108),
			"n_images":                int(199),
			"n_goroutines":            int(39),
		},
		map[string]string{},
	)

	acc.AssertContainsTaggedFields(t,
		"docker_data",
		map[string]interface{}{
			"used":      int64(17300000000),
			"total":     int64(107400000000),
			"available": int64(36530000000),
		},
		map[string]string{
			"unit": "bytes",
		},
	)
	acc.AssertContainsTaggedFields(t,
		"docker_cpu",
		map[string]interface{}{
			"usage_total": uint64(1231652),
		},
		map[string]string{
			"cont_id":    "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
			"cont_name":  "etcd2",
			"cont_image": "quay.io/coreos/etcd:v2.2.2",
			"cpu":        "cpu3",
		},
	)
	acc.AssertContainsTaggedFields(t,
		"docker_mem",
		map[string]interface{}{
			"total_pgpgout":             uint64(0),
			"usage_percent":             float64(0),
			"rss":                       uint64(0),
			"total_writeback":           uint64(0),
			"active_anon":               uint64(0),
			"total_pgmafault":           uint64(0),
			"total_rss":                 uint64(0),
			"total_unevictable":         uint64(0),
			"active_file":               uint64(0),
			"total_mapped_file":         uint64(0),
			"pgpgin":                    uint64(0),
			"total_active_file":         uint64(0),
			"total_active_anon":         uint64(0),
			"total_cache":               uint64(0),
			"inactive_anon":             uint64(0),
			"pgmajfault":                uint64(0),
			"total_inactive_anon":       uint64(0),
			"total_rss_huge":            uint64(0),
			"rss_huge":                  uint64(0),
			"hierarchical_memory_limit": uint64(0),
			"pgpgout":                   uint64(0),
			"unevictable":               uint64(0),
			"total_inactive_file":       uint64(0),
			"writeback":                 uint64(0),
			"total_pgfault":             uint64(0),
			"total_pgpgin":              uint64(0),
			"cache":                     uint64(0),
			"mapped_file":               uint64(0),
			"inactive_file":             uint64(0),
			"max_usage":                 uint64(0),
			"fail_count":                uint64(0),
			"pgfault":                   uint64(0),
			"usage":                     uint64(0),
			"limit":                     uint64(18935443456),
		},
		map[string]string{
			"cont_id":    "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
			"cont_name":  "etcd2",
			"cont_image": "quay.io/coreos/etcd:v2.2.2",
		},
	)

	//fmt.Print(info)
}

{'fraction_non_alphanumeric': 0.1643873273314549, 'fraction_numerical': 0.08710741529791767, 'mean_word_length': 3.319234194122885, 'pattern_counts': {'":': 341, '<': 5, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 13, 'substrings_counts': 14, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1349493', 'n_tokens_mistral': 13170, 'n_tokens_neox': 10863, 'n_words': 1577}