Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor tests in metricbeat in kubernetes module #32706

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 92 additions & 54 deletions metricbeat/module/kubernetes/container/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,58 +25,73 @@ import (
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"

"github.com/elastic/beats/v7/metricbeat/module/kubernetes/util"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"
)

// this file is used for the tests to compare expected result
const testFile = "../_meta/test/stats_summary.json"
gsantoro marked this conversation as resolved.
Show resolved Hide resolved

func TestEventMapping(t *testing.T) {
logger := logp.NewLogger("kubernetes.container")
type ContainerTestSuite struct {
suite.Suite
MetricsRepo *util.MetricsRepo
NodeName string
Namespace string
PodName string
ContainerName string
PodId util.PodId
Logger *logp.Logger
NodeMetrics *util.NodeMetrics
ContainerMetrics *util.ContainerMetrics
}

f, err := os.Open(testFile)
assert.NoError(t, err, "cannot open test file "+testFile)
func (s *ContainerTestSuite) SetupTest() {
s.MetricsRepo = util.NewMetricsRepo()
s.NodeName = "gke-beats-default-pool-a5b33e2e-hdww"
s.Namespace = "default"
s.PodName = "nginx-deployment-2303442956-pcqfc"
s.ContainerName = "nginx"

body, err := ioutil.ReadAll(f)
assert.NoError(t, err, "cannot read test file "+testFile)
s.PodId = util.NewPodId(s.Namespace, s.PodName)

metricsRepo := util.NewMetricsRepo()
s.Logger = logp.NewLogger("kubernetes.container")

nodeName := "gke-beats-default-pool-a5b33e2e-hdww"
s.NodeMetrics = util.NewNodeMetrics()
s.NodeMetrics.CoresAllocatable = util.NewFloat64Metric(2)
s.NodeMetrics.MemoryAllocatable = util.NewFloat64Metric(146227200)

nodeMetrics := util.NewNodeMetrics()
nodeMetrics.CoresAllocatable = util.NewFloat64Metric(2)
nodeMetrics.MemoryAllocatable = util.NewFloat64Metric(146227200)
addNodeMetric(metricsRepo, nodeName, nodeMetrics)
s.ContainerMetrics = util.NewContainerMetrics()
s.ContainerMetrics.MemoryLimit = util.NewFloat64Metric(14622720)
}

namespace := "default"
podName := "nginx-deployment-2303442956-pcqfc"
podId := util.NewPodId(namespace, podName)
containerName := "nginx"
func (s *ContainerTestSuite) ReadTestFile(testFile string) []byte {
f, err := os.Open(testFile)
s.NoError(err, "cannot open test file "+testFile)

containerMetrics := util.NewContainerMetrics()
containerMetrics.MemoryLimit = util.NewFloat64Metric(14622720)
addContainerMetric(metricsRepo, nodeName, podId, containerName, containerMetrics)
body, err := ioutil.ReadAll(f)
s.NoError(err, "cannot read test file "+testFile)

events, err := eventMapping(body, metricsRepo, logger)
assert.NoError(t, err, "error mapping "+testFile)
return body
}

assert.Len(t, events, 1, "got wrong number of events")
func (s *ContainerTestSuite) TestEventMapping() {
s.MetricsRepo.DeleteAllNodeStore()

testCases := map[string]interface{}{
s.addNodeMetric(s.NodeMetrics)
s.addContainerMetric(s.ContainerName, s.ContainerMetrics)

body := s.ReadTestFile(testFile)
events, err := eventMapping(body, s.MetricsRepo, s.Logger)

s.basicTests(events, err)

cpuMemoryTestCases := map[string]interface{}{
"cpu.usage.core.ns": 43959424,
"cpu.usage.nanocores": 11263994,

"logs.available.bytes": int64(98727014400),
"logs.capacity.bytes": int64(101258067968),
"logs.used.bytes": 28672,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you removed them as they are unrleayed with cpu/memory test? I think is better like that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was moved to basicTests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't removed them entirely. I just moved into a function basicTests since they were not related to cpu/memory and in case we wanted to add more tests in the future. pod_test.go is a good example of why it makes sense to move those fields in a separate method

"logs.inodes.count": 6258720,
"logs.inodes.free": 6120096,
"logs.inodes.used": 138624,

"memory.available.bytes": 0,
"memory.usage.bytes": 1462272,
"memory.rss.bytes": 1409024,
Expand All @@ -90,44 +105,67 @@ func TestEventMapping(t *testing.T) {
"memory.usage.node.pct": 0.01,
"memory.usage.limit.pct": 0.1,
"memory.workingset.limit.pct": 0.09943977591036414,

"name": "nginx",

"rootfs.available.bytes": int64(98727014400),
"rootfs.capacity.bytes": int64(101258067968),
"rootfs.used.bytes": 61440,
"rootfs.inodes.used": 21,
}

for k, v := range testCases {
testValue(t, events[0], k, v)
}
s.RunMetricsTests(events[0], cpuMemoryTestCases)

containerEcsFields := ecsfields(events[0], logger)
containerEcsFields := ecsfields(events[0], s.Logger)
testEcs := map[string]interface{}{
"cpu.usage": 0.005631997,
"memory.usage": 0.01,
"name": "nginx",
}
for k, v := range testEcs {
testValue(t, containerEcsFields, k, v)
}
s.RunMetricsTests(containerEcsFields, testEcs)
}

func testValue(t *testing.T, event mapstr.M, field string, value interface{}) {
func (s *ContainerTestSuite) testValue(event mapstr.M, field string, expected interface{}) {
data, err := event.GetValue(field)
assert.NoError(t, err, "Could not read field "+field)
assert.EqualValues(t, data, value, "Wrong value for field "+field)
s.NoError(err, "Could not read field "+field)
s.EqualValues(expected, data, "Wrong value for field "+field)
}

func addContainerMetric(metricsRepo *util.MetricsRepo, nodeName string, podId util.PodId, containerName string, metrics *util.ContainerMetrics) {
nodeStore, _ := metricsRepo.AddNodeStore(nodeName)
podStore, _ := nodeStore.AddPodStore(podId)
func (s *ContainerTestSuite) addContainerMetric(containerName string, containerMetric *util.ContainerMetrics) {
nodeStore, _ := s.MetricsRepo.AddNodeStore(s.NodeName)
podStore, _ := nodeStore.AddPodStore(s.PodId)
containerStore, _ := podStore.AddContainerStore(containerName)
containerStore.SetContainerMetrics(metrics)
containerStore.SetContainerMetrics(containerMetric)
}

func addNodeMetric(metricsRepo *util.MetricsRepo, nodeName string, nodeMetrics *util.NodeMetrics) {
nodeStore, _ := metricsRepo.AddNodeStore(nodeName)
func (s *ContainerTestSuite) addNodeMetric(nodeMetrics *util.NodeMetrics) {
nodeStore, _ := s.MetricsRepo.AddNodeStore(s.NodeName)
nodeStore.SetNodeMetrics(nodeMetrics)
}

func (s *ContainerTestSuite) basicTests(events []mapstr.M, err error) {
s.NoError(err, "error mapping "+testFile)

s.Len(events, 1, "got wrong number of events")

basicTestCases := map[string]interface{}{
"logs.available.bytes": int64(98727014400),
"logs.capacity.bytes": int64(101258067968),
"logs.used.bytes": 28672,
"logs.inodes.count": 6258720,
"logs.inodes.free": 6120096,
"logs.inodes.used": 138624,

"name": "nginx",

"rootfs.available.bytes": int64(98727014400),
"rootfs.capacity.bytes": int64(101258067968),
"rootfs.used.bytes": 61440,
"rootfs.inodes.used": 21,
}

s.RunMetricsTests(events[0], basicTestCases)
}

func (s *ContainerTestSuite) RunMetricsTests(event mapstr.M, testCases map[string]interface{}) {
for k, v := range testCases {
s.testValue(event, k, v)
}
}

func TestContainerTestSuite(t *testing.T) {
suite.Run(t, new(ContainerTestSuite))
}
52 changes: 39 additions & 13 deletions metricbeat/module/kubernetes/node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,51 @@ import (
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"

"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"
)

// this file is used for the tests to compare expected result
const testFile = "../_meta/test/stats_summary.json"
gsantoro marked this conversation as resolved.
Show resolved Hide resolved

func TestEventMapping(t *testing.T) {
logger := logp.NewLogger("kubernetes.node")
type NodeTestSuite struct {
suite.Suite
Logger *logp.Logger
}

func (s *NodeTestSuite) SetupTest() {
s.Logger = logp.NewLogger("kubernetes.node")
}

func (s *NodeTestSuite) ReadTestFile(testFile string) []byte {
f, err := os.Open(testFile)
assert.NoError(t, err, "cannot open test file "+testFile)
s.NoError(err, "cannot open test file "+testFile)

body, err := ioutil.ReadAll(f)
assert.NoError(t, err, "cannot read test file "+testFile)
s.NoError(err, "cannot read test file "+testFile)

return body
}

func (s *NodeTestSuite) TestEventMapping() {
body := s.ReadTestFile(testFile)
event, err := eventMapping(body, s.Logger)

s.basicTests(event, err)
}

func (s *NodeTestSuite) testValue(event mapstr.M, field string, expected interface{}) {
data, err := event.GetValue(field)
s.NoError(err, "Could not read field "+field)
s.EqualValues(expected, data, "Wrong value for field "+field)
}

event, err := eventMapping(body, logger)
assert.NoError(t, err, "error mapping "+testFile)
func (s *NodeTestSuite) basicTests(event mapstr.M, err error) {
s.NoError(err, "error mapping "+testFile)

testCases := map[string]interface{}{
basicTestCases := map[string]interface{}{
"cpu.usage.core.ns": int64(4189523881380),
"cpu.usage.nanocores": 18691146,

Expand Down Expand Up @@ -75,13 +99,15 @@ func TestEventMapping(t *testing.T) {
"runtime.imagefs.used.bytes": 860204379,
}

s.RunMetricsTests(event, basicTestCases)
}

func (s *NodeTestSuite) RunMetricsTests(event mapstr.M, testCases map[string]interface{}) {
for k, v := range testCases {
testValue(t, event, k, v)
s.testValue(event, k, v)
}
}

func testValue(t *testing.T, event mapstr.M, field string, value interface{}) {
data, err := event.GetValue(field)
assert.NoError(t, err, "Could not read field "+field)
assert.EqualValues(t, data, value, "Wrong value for field "+field)
func TestNodeTestSuite(t *testing.T) {
suite.Run(t, new(NodeTestSuite))
}
Loading