Skip to content

Commit

Permalink
[Kubernetes] Update KSM location to avoid updating all state tests (#…
Browse files Browse the repository at this point in the history
…37240)

* Update KSM loc.

* Update KSM loc.

* Update KSM loc.

* Update KSM loc.

* refactor code

* Update metricbeat/module/kubernetes/_meta/test/README.md

Co-authored-by: Andrew Gizas <andreas.gkizas@elastic.co>

* Update metricbeat/module/kubernetes/_meta/test/README.md

Co-authored-by: Andrew Gizas <andreas.gkizas@elastic.co>

* Update metricbeat/module/kubernetes/_meta/test/README.md

Co-authored-by: Andrew Gizas <andreas.gkizas@elastic.co>

* Fix testdata path file

---------

Co-authored-by: Andrew Gizas <andreas.gkizas@elastic.co>
  • Loading branch information
constanca-m and gizas authored Dec 5, 2023
1 parent aeb8d70 commit dfdd982
Show file tree
Hide file tree
Showing 38 changed files with 191 additions and 145 deletions.
54 changes: 40 additions & 14 deletions metricbeat/helper/kubernetes/ktest/ktest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,62 @@
package ktest

import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

p "github.com/elastic/beats/v7/metricbeat/helper/prometheus"
"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
)

// GetTestCases Build test cases from the files and returns them
func GetTestCases(files []string) ptest.TestCases {
func getFiles(folder string) ([]string, error) {
var files []string
entries, err := os.ReadDir(folder)
if err != nil {
return nil, err
}
for _, e := range entries {
files = append(files, filepath.Join(folder, e.Name()))
}
return files, nil
}

// GetTestCases Build test cases based on the files from folder, and the expected files in the expectedFolder
func GetTestCases(folder string, expectedFolder string) (ptest.TestCases, error) {
var cases ptest.TestCases
for i := 0; i < len(files); i++ {

files, err := getFiles(folder)
if err != nil {
return nil, err
}

for _, file := range files {
cases = append(cases,
struct {
MetricsFile string
ExpectedFile string
}{
// the metrics file is inside the parent directory, while the expected file is in the current directory
// Example:
// Metricsfile: ../_meta/test/ksm.v2.4.2
// ExpectedFile: ./_meta/test/ksm.v2.4.2.expected
MetricsFile: files[i],
ExpectedFile: files[i][1:] + ".expected",
MetricsFile: file,
// the expected file will have the path <expectedFolder>/filename.expected
ExpectedFile: filepath.Join(expectedFolder, filepath.Base(file)+".expected"),
},
)
}
return cases
return cases, nil
}

// TestMetricsFamily
// TestMetricsFamilyFromFiles
// This function reads the metric files and checks if the resource fetched metrics exist in it.
// It only checks the family metric, because if the metric doesn't have any data, we don't have a way
// to know the labels from the file.
// The test fails if the metric does not exist in any of the files.
// A warning is printed if the metric is not present in all of them.
// Nothing happens, otherwise.
func TestMetricsFamily(t *testing.T, files []string, mapping *p.MetricsMapping) {
func TestMetricsFamilyFromFiles(t *testing.T, files []string, mapping *p.MetricsMapping) {
metricsFiles := map[string][]string{}
for i := 0; i < len(files); i++ {
content, err := ioutil.ReadFile(files[i])
content, err := os.ReadFile(files[i])
if err != nil {
t.Fatalf("Unknown file %s.", files[i])
}
Expand All @@ -79,3 +95,13 @@ func TestMetricsFamily(t *testing.T, files []string, mapping *p.MetricsMapping)
}

}

// TestMetricsFamilyFromFolder is the same as TestMetricsFamilyFromFiles, but for folder
func TestMetricsFamilyFromFolder(t *testing.T, folder string, mapping *p.MetricsMapping) {
files, err := getFiles(folder)
if err != nil {
t.Fatalf(err.Error())
}

TestMetricsFamilyFromFiles(t, files, mapping)
}
20 changes: 13 additions & 7 deletions metricbeat/module/kubernetes/_meta/test/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
# Kube State Metrics metrics files

Each KSM metrics files has the **name format `ksm.v<version>.plain`**. **The `<version>` should be compatible with the Kubernetes versions we support**. Check the compatibility in the official repository [here](https://github.com/kubernetes/kube-state-metrics#compatibility-matrix).
Each KSM metrics file used for the tests of each `state_*` metricset can be found inside `KSM` directory. Each `state_*` metricset directory will have corresponding `_meta/test*` subfolder with expected files.

**These files are being used in the metricsets that fetch these metrics**: all the `state_*` ones. As of the time of this commit (21.feb.2023), there are two folders that are in use for the `test` file present in each metricset: `test` and `testdata`. Both **these folders require these KSM metrics files** to generate the expected ones. You can check the test file by running `go test -data` to generate the expected files, or simply `go test .` to check against the already present generated files.
Each file has the name format `ksm.v<version>.plain`. The `<version>` should be compatible with the Kubernetes versions we support. Check the compatibility in the official repository [here](https://github.com/kubernetes/kube-state-metrics#compatibility-matrix).

> **_NOTE:_** The expected files inside these two folders are not deleted when running the tests. Remember to delete them if they are from an old version.
**The name of these files needs to end with the suffix `.plain`**. The reason for this is that the `config.yml` file inside each `state_*` metricset `testdata` requires the suffix `.plain` for the metrics files:
It's mandatory for the name of these files to end with the suffix `.plain`. The reason for this is that the `config.yml` file inside each `state_*` metricset `testdata` requires the suffix `.plain` for the metrics files:

```yaml
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
```
Since all metricsets use a `data.json` file for the documentation - this file contains an example of the metrics fields -, **it is necessary that one of these files has the name `docs.plain`**. This file should have the **same content as one of the metrics file of a KSM version** we support. This means that one of the files is duplicated, for example: `ksm.v2.7.0.plain` has the same content as `docs.plain`. This is not a mistake, as having the `ksm.v2.7.0.plain` tells us the metrics of that specific version.
When you update the KSM directory files, remember to run `go test -data` inside each `state_*` metricset directory to generate the expected files. To check against the expected files already present, you can just run `go test .`.

> **TIP**: To run tests and generate the expected files for all state metricsets you can run `go test ./state... --data`. Navigate to `/elastic/beats/metricbeat/module/kubernetes/` to run this command.

> **_NOTE:_** The expected files inside the two folders of each `state_*` mericset (`_meta/test` and `_meta/testdata`) are not deleted when running the tests. Remember to delete them if they are from an old version.


Since all metricsets use a `data.json` file for the documentation - this file contains an example of the metrics fields -, it is necessary that one of these files has the name `docs.plain`. This file needs to be inside `kubernetes/_meta/test` directory. This file should have the same content as one of the metrics file of a KSM version we support.
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ func TestData(t *testing.T) {
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFiles(t, files, mapping)
}
2 changes: 1 addition & 1 deletion metricbeat/module/kubernetes/proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ func TestData(t *testing.T) {
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFiles(t, files, mapping)
}
2 changes: 1 addition & 1 deletion metricbeat/module/kubernetes/scheduler/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ func TestData(t *testing.T) {
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFiles(t, files, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,28 @@ package state_container
import (
"testing"

"github.com/stretchr/testify/require"

k "github.com/elastic/beats/v7/metricbeat/helper/kubernetes/ktest"
"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"
)

var files = []string{
"../_meta/test/ksm.v2.8.2.plain",
"../_meta/test/ksm.v2.9.2.plain",
"../_meta/test/ksm.v2.10.0.plain",
}
var filesFolder = "../_meta/test/KSM"
var expectedFolder = "./_meta/test"

const name = "state_container"

func TestEventMapping(t *testing.T) {
ptest.TestMetricSet(t, "kubernetes", name, k.GetTestCases(files))
testCases, err := k.GetTestCases(filesFolder, expectedFolder)
require.Equal(t, err, nil)
ptest.TestMetricSet(t, "kubernetes", name, testCases)
}

func TestData(t *testing.T) {
mbtest.TestDataFiles(t, "kubernetes", name)
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFolder(t, filesFolder, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
15 changes: 8 additions & 7 deletions metricbeat/module/kubernetes/state_cronjob/state_cronjob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,29 @@ package state_cronjob
import (
"testing"

"github.com/stretchr/testify/require"

mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"

k "github.com/elastic/beats/v7/metricbeat/helper/kubernetes/ktest"
"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
)

var files = []string{
"../_meta/test/ksm.v2.8.2.plain",
"../_meta/test/ksm.v2.9.2.plain",
"../_meta/test/ksm.v2.10.0.plain",
}
var filesFolder = "../_meta/test/KSM"
var expectedFolder = "./_meta/test"

const name = "state_cronjob"

func TestEventMapping(t *testing.T) {
ptest.TestMetricSet(t, "kubernetes", name, k.GetTestCases(files))
testCases, err := k.GetTestCases(filesFolder, expectedFolder)
require.Equal(t, err, nil)
ptest.TestMetricSet(t, "kubernetes", name, testCases)
}

func TestData(t *testing.T) {
mbtest.TestDataFiles(t, "kubernetes", name)
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFolder(t, filesFolder, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package state_daemonset
import (
"testing"

"github.com/stretchr/testify/require"

k "github.com/elastic/beats/v7/metricbeat/helper/kubernetes/ktest"

"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
Expand All @@ -30,22 +32,21 @@ import (
_ "github.com/elastic/beats/v7/metricbeat/module/kubernetes"
)

var files = []string{
"../_meta/test/ksm.v2.8.2.plain",
"../_meta/test/ksm.v2.9.2.plain",
"../_meta/test/ksm.v2.10.0.plain",
}
var filesFolder = "../_meta/test/KSM"
var expectedFolder = "./_meta/test"

const name = "state_daemonset"

func TestEventMapping(t *testing.T) {
ptest.TestMetricSet(t, "kubernetes", name, k.GetTestCases(files))
testCases, err := k.GetTestCases(filesFolder, expectedFolder)
require.Equal(t, err, nil)
ptest.TestMetricSet(t, "kubernetes", name, testCases)
}

func TestData(t *testing.T) {
mbtest.TestDataFiles(t, "kubernetes", name)
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFolder(t, filesFolder, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,30 @@ package state_deployment
import (
"testing"

"github.com/stretchr/testify/require"

k "github.com/elastic/beats/v7/metricbeat/helper/kubernetes/ktest"

"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"
_ "github.com/elastic/beats/v7/metricbeat/module/kubernetes"
)

var files = []string{
"../_meta/test/ksm.v2.8.2.plain",
"../_meta/test/ksm.v2.9.2.plain",
"../_meta/test/ksm.v2.10.0.plain",
}
var filesFolder = "../_meta/test/KSM"
var expectedFolder = "./_meta/test"

const name = "state_deployment"

func TestEventMapping(t *testing.T) {
ptest.TestMetricSet(t, "kubernetes", name, k.GetTestCases(files))
testCases, err := k.GetTestCases(filesFolder, expectedFolder)
require.Equal(t, err, nil)
ptest.TestMetricSet(t, "kubernetes", name, testCases)
}

func TestData(t *testing.T) {
mbtest.TestDataFiles(t, "kubernetes", name)
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFolder(t, filesFolder, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
15 changes: 8 additions & 7 deletions metricbeat/module/kubernetes/state_job/state_job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,30 @@ package state_job
import (
"testing"

"github.com/stretchr/testify/require"

k "github.com/elastic/beats/v7/metricbeat/helper/kubernetes/ktest"

"github.com/elastic/beats/v7/metricbeat/helper/prometheus/ptest"
mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing"
_ "github.com/elastic/beats/v7/metricbeat/module/kubernetes"
)

var files = []string{
"../_meta/test/ksm.v2.8.2.plain",
"../_meta/test/ksm.v2.9.2.plain",
"../_meta/test/ksm.v2.10.0.plain",
}
var filesFolder = "../_meta/test/KSM"
var expectedFolder = "./_meta/test"

const name = "state_job"

func TestEventMapping(t *testing.T) {
ptest.TestMetricSet(t, "kubernetes", name, k.GetTestCases(files))
testCases, err := k.GetTestCases(filesFolder, expectedFolder)
require.Equal(t, err, nil)
ptest.TestMetricSet(t, "kubernetes", name, testCases)
}

func TestData(t *testing.T) {
mbtest.TestDataFiles(t, "kubernetes", name)
}

func TestMetricsFamily(t *testing.T) {
k.TestMetricsFamily(t, files, mapping)
k.TestMetricsFamilyFromFolder(t, filesFolder, mapping)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type: http
url: "/metrics"
suffix: plain
path: "../_meta/test"
path: "../_meta/test/KSM"
Loading

0 comments on commit dfdd982

Please sign in to comment.