예제 #1
0
/*
TestEventGeneratorGetCpuEventFirstPass simulates the case when a cpu event should be generated

It simulates following status:
  - a common container
  - a common CPU stats

This test checks parameters passed to the calculator and checks that the event generated is well formatted.
*/
func TestEventGeneratorGetCpuEvent(t *testing.T) {
	// GIVEN
	// docker socket
	socket := "unix:///some/docker/socket"

	// a container
	labels := map[string]string{}
	labels["label1"] = "value1"
	labels["label2"] = "value2"
	containerId := "container_id"
	container := docker.APIContainers{
		ID:         containerId,
		Image:      "container_image",
		Command:    "container command",
		Created:    9876543210,
		Status:     "Up",
		Ports:      []docker.APIPort{{PrivatePort: 1234, PublicPort: 4567, Type: "portType", IP: "123.456.879.1"}},
		SizeRw:     123,
		SizeRootFs: 456,
		Names:      []string{"/name1", "name1/fake"},
		Labels:     labels,
		Networks:   docker.NetworkList{},
	}

	// CPU stats from Docker API
	preCPUStats := getCPUStats(1)
	cpuStats := getCPUStats(2)

	// main stats object
	var stats = new(docker.Stats)
	stats.Read = time.Now()
	stats.CPUStats = cpuStats
	stats.PreCPUStats = preCPUStats

	// mocking calculator
	// first - generate expected calls (CPUStats to CPUData conversion)
	cpuData := calculator.CPUData{
		PerCpuUsage:       cpuStats.CPUUsage.PercpuUsage,
		TotalUsage:        cpuStats.CPUUsage.TotalUsage,
		UsageInKernelmode: cpuStats.CPUUsage.UsageInKernelmode,
		UsageInUsermode:   cpuStats.CPUUsage.UsageInUsermode,
	}

	preCPUData := calculator.CPUData{
		PerCpuUsage:       preCPUStats.CPUUsage.PercpuUsage,
		TotalUsage:        preCPUStats.CPUUsage.TotalUsage,
		UsageInKernelmode: preCPUStats.CPUUsage.UsageInKernelmode,
		UsageInUsermode:   preCPUStats.CPUUsage.UsageInUsermode,
	}

	// second - instantiate mock
	// calculator will no be called for em1 network, it will generate zero-values event for em1
	mockedCalculatorFactory := new(mocks.CalculatorFactory)
	mockedCPUCalculator := getMockedCPUCalculator(1.0)
	mockedCalculatorFactory.On("NewCPUCalculator", preCPUData, cpuData).Return(mockedCPUCalculator)

	// expected events
	expectedEvent := common.MapStr{
		"@timestamp":    common.Time(stats.Read),
		"type":          "cpu",
		"containerID":   container.ID,
		"containerName": "name1",
		"containerLabels": []common.MapStr{
			{
				"key":   "label1",
				"value": "value1",
			},
			{
				"key":   "label2",
				"value": "value2",
			},
		},
		"dockerSocket": &socket,
		"cpu": common.MapStr{
			"percpuUsage":       mockedCPUCalculator.PerCpuUsage(),
			"totalUsage":        mockedCPUCalculator.TotalUsage(),
			"usageInKernelmode": mockedCPUCalculator.UsageInKernelmode(),
			"usageInUsermode":   mockedCPUCalculator.UsageInUsermode(),
		},
	}

	// the eventGenerator to test
	var eventGenerator = EventGenerator{&socket, EGNetworkStats{}, EGBlkioStats{}, mockedCalculatorFactory, time.Second}

	// WHEN
	event := eventGenerator.GetCpuEvent(&container, stats)

	// THEN
	// check returned events
	assert.True(t, equalEvent(expectedEvent, event))
}
예제 #2
0
/*
TestEventGeneratorGetNetworksEventFirstPass simulates the case when a new network event should be generated

It simulates following status:
  - a common container
  - network stats with two networks "eth0" and "em1"

The network "eth0" already have an saved status from previous tick.

This test checks that it generate two network events:
  - an event for "eth0" with calculated data from saved stats (+ new stats saved)
  - an event for "em1" with zeros values (+ new stats saved)
*/
func TestEventGeneratorGetNetworksEventFirstPass(t *testing.T) {
	// GIVEN
	// docker socket
	socket := "unix:///some/docker/socket"
	// old and current timestamps
	oldTimestamp := time.Now()
	period := time.Second
	newTimestamp := oldTimestamp.Add(period)

	// a container
	labels := map[string]string{}
	labels["label1"] = "value1"
	labels["label2"] = "value2"
	containerId := "container_id"
	container := docker.APIContainers{
		ID:         containerId,
		Image:      "container_image",
		Command:    "container command",
		Created:    9876543210,
		Status:     "Up",
		Ports:      []docker.APIPort{{PrivatePort: 1234, PublicPort: 4567, Type: "portType", IP: "123.456.879.1"}},
		SizeRw:     123,
		SizeRootFs: 456,
		Names:      []string{"/name1", "name1/fake"},
		Labels:     labels,
		Networks:   docker.NetworkList{},
	}

	// network stats from Docker API
	networkStatsMap := map[string]docker.NetworkStats{}
	networkStatsMap["eth0"] = docker.NetworkStats{
		RxBytes:   10,
		RxDropped: 20,
		RxErrors:  30,
		RxPackets: 40,
		TxBytes:   50,
		TxDropped: 60,
		TxErrors:  70,
		TxPackets: 80,
	}
	networkStatsMap["em1"] = docker.NetworkStats{
		RxBytes:   90,
		RxDropped: 100,
		RxErrors:  110,
		RxPackets: 120,
		TxBytes:   130,
		TxDropped: 140,
		TxErrors:  150,
		TxPackets: 160,
	}

	// main stats object
	var stats = new(docker.Stats)
	stats.Read = newTimestamp
	stats.Networks = networkStatsMap

	// saved network status (em1 does not already exists)
	oldNetworkData := map[string]map[string]calculator.NetworkData{}
	oldNetworkData[containerId] = map[string]calculator.NetworkData{}
	oldNetworkData[containerId]["eth0"] = calculator.NetworkData{
		Time:      oldTimestamp,
		RxBytes:   1,
		RxDropped: 2,
		RxErrors:  3,
		RxPackets: 4,
		TxBytes:   5,
		TxDropped: 6,
		TxErrors:  7,
		TxPackets: 8,
	}

	// mocking calculators
	// first - generate expected calls (NetworkStats to NetworkData conversion)
	newNetworkData := map[string]calculator.NetworkData{}
	newNetworkData["eth0"] = calculator.NetworkData{
		Time:      newTimestamp,
		RxBytes:   10,
		RxDropped: 20,
		RxErrors:  30,
		RxPackets: 40,
		TxBytes:   50,
		TxDropped: 60,
		TxErrors:  70,
		TxPackets: 80,
	}
	newNetworkData["em1"] = calculator.NetworkData{
		Time:      newTimestamp,
		RxBytes:   90,
		RxDropped: 100,
		RxErrors:  110,
		RxPackets: 120,
		TxBytes:   130,
		TxDropped: 140,
		TxErrors:  150,
		TxPackets: 160,
	}

	// second - instantiate mock
	// calculator will no be called for em1 network, it will generate zero-values event for em1
	mockedCalculatorFactory := new(mocks.CalculatorFactory)
	mockedNetworkCalculatorEth0 := getMockedNetworkCalculator(1.0)
	mockedCalculatorFactory.On("NewNetworkCalculator", oldNetworkData[containerId]["eth0"], newNetworkData["eth0"]).Return(mockedNetworkCalculatorEth0)

	// expected events
	expectedEvents := []common.MapStr{}
	expectedEvents = append(expectedEvents,
		common.MapStr{
			"@timestamp":    common.Time(newTimestamp),
			"type":          "net",
			"containerID":   container.ID,
			"containerName": "name1",
			"containerLabels": []common.MapStr{
				{
					"key":   "label1",
					"value": "value1",
				},
				{
					"key":   "label2",
					"value": "value2",
				},
			},
			"dockerSocket": &socket,
			"net": common.MapStr{
				"name":         "eth0",
				"rxBytes_ps":   mockedNetworkCalculatorEth0.GetRxBytesPerSecond(),
				"rxDropped_ps": mockedNetworkCalculatorEth0.GetRxDroppedPerSecond(),
				"rxErrors_ps":  mockedNetworkCalculatorEth0.GetRxErrorsPerSecond(),
				"rxPackets_ps": mockedNetworkCalculatorEth0.GetRxPacketsPerSecond(),
				"txBytes_ps":   mockedNetworkCalculatorEth0.GetTxBytesPerSecond(),
				"txDropped_ps": mockedNetworkCalculatorEth0.GetTxDroppedPerSecond(),
				"txErrors_ps":  mockedNetworkCalculatorEth0.GetTxErrorsPerSecond(),
				"txPackets_ps": mockedNetworkCalculatorEth0.GetTxPacketsPerSecond(),
			}},
		common.MapStr{
			"@timestamp":    common.Time(newTimestamp),
			"type":          "net",
			"containerID":   container.ID,
			"containerName": "name1",
			"containerLabels": []common.MapStr{
				{
					"key":   "label1",
					"value": "value1",
				},
				{
					"key":   "label2",
					"value": "value2",
				},
			},
			"dockerSocket": &socket,
			"net": common.MapStr{
				"name":         "em1",
				"rxBytes_ps":   0,
				"rxDropped_ps": 0,
				"rxErrors_ps":  0,
				"rxPackets_ps": 0,
				"txBytes_ps":   0,
				"txDropped_ps": 0,
				"txErrors_ps":  0,
				"txPackets_ps": 0,
			}})

	// the eventGenerator to test
	var eventGenerator = EventGenerator{&socket, EGNetworkStats{M: oldNetworkData}, EGBlkioStats{}, mockedCalculatorFactory, period}

	// WHEN
	events := eventGenerator.GetNetworksEvent(&container, stats)

	// THEN
	// check returned events
	assert.Equal(t, len(expectedEvents), 2)

	for i := range expectedEvents {
		checked := false
		for j := range events {
			if equalEvent(expectedEvents[i], events[j]) {
				checked = true
				break
			}
		}
		if !checked {
			assert.Fail(t, "unable to find network in events: %v", expectedEvents[i].String())
		}
	}

	// check that new stats saved
	assert.Equal(t, eventGenerator.NetworkStats.M[container.ID]["eth0"], newNetworkData["eth0"])
	assert.Equal(t, eventGenerator.NetworkStats.M[container.ID]["em1"], newNetworkData["em1"])
}
예제 #3
0
/*
TestEventGeneratorGetNetworksEvent simulates the case when a saved network should be cleaned from saved status

It simulates following status:
  - a common container
  - network stats with one network "eth0"

Networks "eth0" have an saved status from previous tick.
An existing saved status for "em1" network is too old and should be removed.

This test checks that it generate one network event:
  - an event for "eth0" with calculated data from saved stats (+ new stats saved)
  - the "em1" saved network status should be removed
*/
func TestEventGeneratorGetNetworksEventCleanSavedEvents(t *testing.T) {
	// GIVEN
	// docker socket
	socket := "unix:///some/docker/socket"

	// old and current timestamps
	oldTimestamp := time.Now()
	veryOldTimestamp := oldTimestamp.AddDate(0, -1, 0)
	period := time.Second
	newTimestamp := oldTimestamp.Add(period)

	// a container
	labels := map[string]string{}
	labels["label1"] = "value1"
	labels["label2"] = "value2"
	containerId := "container_id"
	container := docker.APIContainers{
		ID:         containerId,
		Image:      "container_image",
		Command:    "container command",
		Created:    9876543210,
		Status:     "Up",
		Ports:      []docker.APIPort{{PrivatePort: 1234, PublicPort: 4567, Type: "portType", IP: "123.456.879.1"}},
		SizeRw:     123,
		SizeRootFs: 456,
		Names:      []string{"/name1", "name1/fake"},
		Labels:     labels,
		Networks:   docker.NetworkList{},
	}

	// network stats from Docker API
	networkStatsMap := map[string]docker.NetworkStats{}
	networkStatsMap["eth0"] = docker.NetworkStats{
		RxBytes:   10,
		RxDropped: 20,
		RxErrors:  30,
		RxPackets: 40,
		TxBytes:   50,
		TxDropped: 60,
		TxErrors:  70,
		TxPackets: 80,
	}

	// main stats object
	var stats = new(docker.Stats)
	stats.Read = newTimestamp
	stats.Networks = networkStatsMap

	// saved network status
	oldNetworkData := map[string]map[string]calculator.NetworkData{}
	oldNetworkData[containerId] = map[string]calculator.NetworkData{}
	oldNetworkData[containerId]["eth0"] = calculator.NetworkData{
		Time:      oldTimestamp,
		RxBytes:   1,
		RxDropped: 2,
		RxErrors:  3,
		RxPackets: 4,
		TxBytes:   5,
		TxDropped: 6,
		TxErrors:  7,
		TxPackets: 8,
	}
	// em1 has a very old timestamp, and should be removed because no em1 event come from stats API
	oldNetworkData[containerId]["em1"] = calculator.NetworkData{
		Time:      veryOldTimestamp,
		RxBytes:   9,
		RxDropped: 10,
		RxErrors:  11,
		RxPackets: 12,
		TxBytes:   13,
		TxDropped: 14,
		TxErrors:  15,
		TxPackets: 16,
	}

	// mocking calculators
	// first - generate expected calls (NetworkStats to NetworkData conversion)
	newNetworkData := map[string]calculator.NetworkData{}
	newNetworkData["eth0"] = calculator.NetworkData{
		Time:      newTimestamp,
		RxBytes:   10,
		RxDropped: 20,
		RxErrors:  30,
		RxPackets: 40,
		TxBytes:   50,
		TxDropped: 60,
		TxErrors:  70,
		TxPackets: 80,
	}

	// second - instantiate mock
	mockedCalculatorFactory := new(mocks.CalculatorFactory)
	mockedNetworkCalculatorEth0 := getMockedNetworkCalculator(1.0)
	mockedCalculatorFactory.On("NewNetworkCalculator", oldNetworkData[containerId]["eth0"], newNetworkData["eth0"]).Return(mockedNetworkCalculatorEth0)

	// expected events
	expectedEvents := []common.MapStr{}
	expectedEvents = append(expectedEvents,
		common.MapStr{
			"@timestamp":    common.Time(newTimestamp),
			"type":          "net",
			"containerID":   container.ID,
			"containerName": "name1",
			"containerLabels": []common.MapStr{
				{
					"key":   "label1",
					"value": "value1",
				},
				{
					"key":   "label2",
					"value": "value2",
				},
			},
			"dockerSocket": &socket,
			"net": common.MapStr{
				"name":         "eth0",
				"rxBytes_ps":   mockedNetworkCalculatorEth0.GetRxBytesPerSecond(),
				"rxDropped_ps": mockedNetworkCalculatorEth0.GetRxDroppedPerSecond(),
				"rxErrors_ps":  mockedNetworkCalculatorEth0.GetRxErrorsPerSecond(),
				"rxPackets_ps": mockedNetworkCalculatorEth0.GetRxPacketsPerSecond(),
				"txBytes_ps":   mockedNetworkCalculatorEth0.GetTxBytesPerSecond(),
				"txDropped_ps": mockedNetworkCalculatorEth0.GetTxDroppedPerSecond(),
				"txErrors_ps":  mockedNetworkCalculatorEth0.GetTxErrorsPerSecond(),
				"txPackets_ps": mockedNetworkCalculatorEth0.GetTxPacketsPerSecond(),
			}})

	// the eventGenerator to test
	var eventGenerator = EventGenerator{&socket, EGNetworkStats{M: oldNetworkData}, EGBlkioStats{}, mockedCalculatorFactory, period}

	// WHEN
	events := eventGenerator.GetNetworksEvent(&container, stats)

	// THEN
	// check returned events
	for i := 0; i < len(expectedEvents); i++ {
		assert.True(t, equalEvent(expectedEvents[i], events[i]))
	}

	// check that new stats saved
	assert.Equal(t, eventGenerator.NetworkStats.M[container.ID]["eth0"], newNetworkData["eth0"])

	// check that expired state has been deleted
	_, ok := eventGenerator.NetworkStats.M[container.ID]["em1"]
	if ok {
		assert.Fail(t, "Expired event has not been deleted")
	}
}
예제 #4
0
/*
TestEventGeneratorGetBlkioEventCleanSavedEvents simulates the case when method should clean old blkio stats

It simulates following status:
  - a common container
  - blkio stats with saved status

The blkio stats for this container already have an saved status from previous tick.
A saved event is too old and should be remove from saved stats.
*/
func TestEventGeneratorGetBlkioEventCleanSavedEvents(t *testing.T) {
	// GIVEN
	// docker socket
	socket := "unix:///some/docker/socket"

	// old and current timestamps
	oldTimestamp := time.Now()
	veryOldTimestamp := oldTimestamp.AddDate(0, -1, 0)
	period := time.Second
	newTimestamp := oldTimestamp.Add(period)

	// a container
	labels := map[string]string{}
	labels["label1"] = "value1"
	labels["label2"] = "value2"
	containerId := "container_id"
	anotherContainerId := "container_id2"
	container := docker.APIContainers{
		ID:         containerId,
		Image:      "container_image",
		Command:    "container command",
		Created:    9876543210,
		Status:     "Up",
		Ports:      []docker.APIPort{{PrivatePort: 1234, PublicPort: 4567, Type: "portType", IP: "123.456.879.1"}},
		SizeRw:     123,
		SizeRootFs: 456,
		Names:      []string{"/name1", "name1/fake"},
		Labels:     labels,
		Networks:   docker.NetworkList{},
	}

	// main stats object
	var stats = getBlkioStats(newTimestamp, 10, 20, 30)

	// saved blkio stats
	oldBlkioData := map[string]calculator.BlkioData{}
	oldBlkioData[containerId] = calculator.BlkioData{
		Time:   oldTimestamp,
		Reads:  1,
		Writes: 2,
		Totals: 3,
	}
	// another container has a very old blkio stats
	oldBlkioData[anotherContainerId] = calculator.BlkioData{
		Time:   veryOldTimestamp,
		Reads:  4,
		Writes: 5,
		Totals: 6,
	}

	// mocking calculators
	// first - generate expected calls (BlkioStats to BlkioData conversion)
	newBlkioData := calculator.BlkioData{
		Time:   newTimestamp,
		Reads:  10,
		Writes: 20,
		Totals: 30,
	}

	// second - instantiate mock
	mockedCalculatorFactory := new(mocks.CalculatorFactory)
	mockedBlkioCalculator := getMockedBlkioCalculator(1)
	mockedCalculatorFactory.On("NewBlkioCalculator", oldBlkioData[containerId], newBlkioData).Return(mockedBlkioCalculator)

	// expected events
	expectedEvent := common.MapStr{
		"@timestamp":    common.Time(newTimestamp),
		"type":          "blkio",
		"containerID":   container.ID,
		"containerName": "name1",
		"containerLabels": []common.MapStr{
			{
				"key":   "label1",
				"value": "value1",
			},
			{
				"key":   "label2",
				"value": "value2",
			},
		},
		"dockerSocket": &socket,
		"blkio": common.MapStr{
			"read_ps":  mockedBlkioCalculator.GetReadPs(),
			"write_ps": mockedBlkioCalculator.GetWritePs(),
			"total_ps": mockedBlkioCalculator.GetTotalPs(),
		},
	}

	// the eventGenerator to test
	var eventGenerator = EventGenerator{&socket, EGNetworkStats{}, EGBlkioStats{M: oldBlkioData}, mockedCalculatorFactory, period}

	// WHEN
	event := eventGenerator.GetBlkioEvent(&container, &stats)

	// THEN
	// check returned events
	assert.True(t, equalEvent(expectedEvent, event))

	// check that new stats saved
	assert.Equal(t, eventGenerator.BlkioStats.M[container.ID], newBlkioData)

	// check that expired state has been deleted
	_, ok := eventGenerator.BlkioStats.M[anotherContainerId]
	if ok {
		assert.Fail(t, "Expired event has not been deleted")
	}
}