Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1b884dc

Browse files
committedApr 2, 2020
Add test for documented fields check for metricsets without a http input (elastic#17334)
* add test for documented fields * changelog * work on test * add test for testdata * fmt update (cherry picked from commit e545836)
1 parent 407cd5a commit 1b884dc

File tree

12 files changed

+82
-84
lines changed

12 files changed

+82
-84
lines changed
 

‎CHANGELOG.next.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
359359
- Add Storage metricsets to GCP module {pull}15598[15598]
360360
- Release vsphere module as GA. {issue}15798[15798] {pull}17119[17119]
361361
- Add PubSub metricset to Google Cloud Platform module {pull}15536[15536]
362+
- Added documentation for running Metricbeat in Cloud Foundry. {pull}17275[17275]
363+
- Add test for documented fields check for metricsets without a http input. {issue}17315[17315] {pull}17334[17334]
362364
- Add final tests and move label to GA for the azure module in metricbeat. {pull}17319[17319]
363365
- Added documentation for running Metricbeat in Cloud Foundry. {pull}17275[17275]
364366

‎metricbeat/mb/testing/testdata.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,22 @@ func TestDataFilesWithConfig(t *testing.T, module, metricSet string, config Data
171171
}
172172
}
173173

174+
// TestMetricsetFieldsDocumented checks metricset fields are documented from metricsets that cannot run `TestDataFiles` test which contains this check
175+
func TestMetricsetFieldsDocumented(t *testing.T, metricSet mb.MetricSet, events []mb.Event) {
176+
var data []common.MapStr
177+
for _, e := range events {
178+
beatEvent := StandardizeEvent(metricSet, e, mb.AddMetricSetInfo)
179+
data = append(data, beatEvent.Fields)
180+
}
181+
182+
if err := checkDocumented(data, nil); err != nil {
183+
t.Errorf("%v: check if fields are documented in `metricbeat/%s/%s/_meta/fields.yml` "+
184+
"file or run 'make update' on Metricbeat folder to update fields in `metricbeat/fields.yml`",
185+
err, metricSet.Module().Name(), metricSet.Name())
186+
}
187+
188+
}
189+
174190
func runTest(t *testing.T, file string, module, metricSetName string, config DataConfig) {
175191
// starts a server serving the given file under the given url
176192
s := server(t, file, config.URL)
@@ -215,7 +231,7 @@ func runTest(t *testing.T, file string, module, metricSetName string, config Dat
215231
return h1 < h2
216232
})
217233

218-
if err := checkDocumented(t, data, config.OmitDocumentedFieldsCheck); err != nil {
234+
if err := checkDocumented(data, config.OmitDocumentedFieldsCheck); err != nil {
219235
t.Errorf("%v: check if fields are documented in `metricbeat/%s/%s/_meta/fields.yml` "+
220236
"file or run 'make update' on Metricbeat folder to update fields in `metricbeat/fields.yml`",
221237
err, module, metricSetName)
@@ -300,7 +316,7 @@ func writeDataJSON(t *testing.T, data common.MapStr, path string) {
300316
}
301317

302318
// checkDocumented checks that all fields which show up in the events are documented
303-
func checkDocumented(t *testing.T, data []common.MapStr, omitFields []string) error {
319+
func checkDocumented(data []common.MapStr, omitFields []string) error {
304320
fieldsData, err := asset.GetFields("metricbeat")
305321
if err != nil {
306322
return err
@@ -310,7 +326,6 @@ func checkDocumented(t *testing.T, data []common.MapStr, omitFields []string) er
310326
if err != nil {
311327
return err
312328
}
313-
314329
documentedFields := fields.GetKeys()
315330
keys := map[string]interface{}{}
316331

@@ -350,12 +365,19 @@ func documentedFieldCheck(foundKeys common.MapStr, knownKeys map[string]interfac
350365
if found {
351366
continue
352367
}
353-
354-
// last case `status_codes.*`:
368+
// case `status_codes.*`:
355369
prefix := strings.Join(splits[0:len(splits)-1], ".")
356370
if _, ok := knownKeys[prefix+".*"]; ok {
357371
continue
358372
}
373+
// should cover scenarios as status_codes.*.*` and `azure.compute_vm_scaleset.*.*`
374+
if len(splits) > 2 {
375+
prefix = strings.Join(splits[0:len(splits)-2], ".")
376+
if _, ok := knownKeys[prefix+".*.*"]; ok {
377+
continue
378+
}
379+
}
380+
359381
return errors.Errorf("field missing '%s'", foundKey)
360382
}
361383
}

‎metricbeat/mb/testing/testdata_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ package testing
2020
import (
2121
"testing"
2222

23+
"github.com/elastic/beats/v7/libbeat/common"
24+
2325
"github.com/stretchr/testify/assert"
2426
)
2527

@@ -40,3 +42,46 @@ func TestOmitDocumentedField(t *testing.T) {
4042
assert.Equal(t, tt.result, result)
4143
}
4244
}
45+
46+
func TestDocumentedFieldCheck(t *testing.T) {
47+
foundKeys := common.MapStr{
48+
"hello": "hello",
49+
"elasticsearch.stats": "stats1",
50+
}
51+
omitfields := []string{
52+
"hello",
53+
}
54+
knownKeys := map[string]interface{}{
55+
"elasticsearch.stats": "key1",
56+
}
57+
err := documentedFieldCheck(foundKeys, knownKeys, omitfields)
58+
//error should be nil, as `hello` field is ignored and `elasticsearch.stats` field is defined
59+
assert.NoError(t, err)
60+
61+
foundKeys = common.MapStr{
62+
"elasticsearch.stats.cpu": "stats2",
63+
"elasticsearch.metrics.requests.count": "requests2",
64+
}
65+
66+
knownKeys = map[string]interface{}{
67+
"elasticsearch.stats.*": "key1",
68+
"elasticsearch.metrics.*.*": "hello1",
69+
}
70+
// error should be nil as the foundKeys are covered by the `prefix` cases
71+
err = documentedFieldCheck(foundKeys, knownKeys, omitfields)
72+
assert.NoError(t, err)
73+
74+
foundKeys = common.MapStr{
75+
"elasticsearch.stats.cpu": "stats2",
76+
"elasticsearch.metrics.requests.count": "requests2",
77+
}
78+
79+
knownKeys = map[string]interface{}{
80+
"elasticsearch.*": "key1",
81+
"elasticsearch.metrics.*": "hello1",
82+
}
83+
// error should not be nil as the foundKeys are not covered by the `prefix` cases
84+
err = documentedFieldCheck(foundKeys, knownKeys, omitfields)
85+
assert.Error(t, err, "field missing 'elasticsearch.stats.cpu'")
86+
87+
}

‎x-pack/metricbeat/module/azure/compute_vm/compute_vm_integration_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ func TestFetchMetricset(t *testing.T) {
2525
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2626
}
2727
assert.NotEmpty(t, events)
28-
test.TestFieldsDocumentation(t, events)
29-
28+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
3029
}
3130

3231
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/compute_vm_scaleset/compute_vm_scaleset_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestFetchMetricset(t *testing.T) {
2525
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2626
}
2727
assert.NotEmpty(t, events)
28-
test.TestFieldsDocumentation(t, events)
28+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
2929
}
3030

3131
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/container_instance/container_instance_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestFetchMetricset(t *testing.T) {
2828
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2929
}
3030
assert.NotEmpty(t, events)
31-
test.TestFieldsDocumentation(t, events)
31+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
3232
}
3333

3434
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/container_registry/container_registry_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestFetchMetricset(t *testing.T) {
2828
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2929
}
3030
assert.NotEmpty(t, events)
31-
test.TestFieldsDocumentation(t, events)
31+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
3232
}
3333

3434
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/container_service/container_service_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestFetchMetricset(t *testing.T) {
2828
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2929
}
3030
assert.NotEmpty(t, events)
31-
test.TestFieldsDocumentation(t, events)
31+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
3232
}
3333

3434
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/database_account/database_account_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestFetchMetricset(t *testing.T) {
2525
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2626
}
2727
assert.NotEmpty(t, events)
28-
test.TestFieldsDocumentation(t, events)
28+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
2929
}
3030

3131
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/monitor/monitor_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestFetchMetricset(t *testing.T) {
2525
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2626
}
2727
assert.NotEmpty(t, events)
28-
test.TestFieldsDocumentation(t, events)
28+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
2929
}
3030

3131
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/storage/storage_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestFetchMetricset(t *testing.T) {
2525
t.Fatalf("Expected 0 error, had %d. %v\n", len(errs), errs)
2626
}
2727
assert.NotEmpty(t, events)
28-
test.TestFieldsDocumentation(t, events)
28+
mbtest.TestMetricsetFieldsDocumented(t, metricSet, events)
2929
}
3030

3131
func TestData(t *testing.T) {

‎x-pack/metricbeat/module/azure/test/integration.go

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@
55
package test
66

77
import (
8-
"errors"
98
"os"
109
"testing"
11-
12-
"github.com/stretchr/testify/assert"
13-
14-
"github.com/elastic/beats/v7/metricbeat/mb"
1510
)
1611

1712
// GetConfig function gets azure credentials for integration tests.
@@ -45,68 +40,3 @@ func GetConfig(t *testing.T, metricSetName string) map[string]interface{} {
4540
"subscription_id": subId,
4641
}
4742
}
48-
49-
// TestFieldsDocumentation func checks if all the documented fields have the expected type
50-
func TestFieldsDocumentation(t *testing.T, events []mb.Event) {
51-
for _, event := range events {
52-
// RootField
53-
checkIsDocumented("service.name", "string", event, t)
54-
checkIsDocumented("cloud.provider", "string", event, t)
55-
checkIsDocumented("cloud.region", "string", event, t)
56-
checkIsDocumented("cloud.instance.name", "string", event, t)
57-
checkIsDocumented("cloud.instance.id", "string", event, t)
58-
59-
// MetricSetField
60-
checkIsDocumented("azure.timegrain", "string", event, t)
61-
checkIsDocumented("azure.subscription_id", "string", event, t)
62-
checkIsDocumented("azure.namespace", "string", event, t)
63-
checkIsDocumented("azure.resource.type", "string", event, t)
64-
checkIsDocumented("azure.resource.group", "string", event, t)
65-
}
66-
}
67-
68-
// checkIsDocumented function checks a given field type and compares it with the expected type for integration tests.
69-
// this implementation is only temporary, will be replaced by issue https://github.com/elastic/beats/issues/17315
70-
func checkIsDocumented(metricName string, expectedType string, event mb.Event, t *testing.T) {
71-
t.Helper()
72-
73-
ok1, err1 := event.MetricSetFields.HasKey(metricName)
74-
ok2, err2 := event.RootFields.HasKey(metricName)
75-
if ok1 || ok2 {
76-
if ok1 {
77-
assert.NoError(t, err1)
78-
metricValue, err := event.MetricSetFields.GetValue(metricName)
79-
assert.NoError(t, err)
80-
err = compareType(metricValue, expectedType, metricName)
81-
assert.NoError(t, err)
82-
t.Log("Succeed: Field " + metricName + " matches type " + expectedType)
83-
} else if ok2 {
84-
assert.NoError(t, err2)
85-
rootValue, err := event.RootFields.GetValue(metricName)
86-
assert.NoError(t, err)
87-
err = compareType(rootValue, expectedType, metricName)
88-
assert.NoError(t, err)
89-
t.Log("Succeed: Field " + metricName + " matches type " + expectedType)
90-
}
91-
} else {
92-
t.Log("Field " + metricName + " does not exist in metric set fields")
93-
}
94-
}
95-
96-
func compareType(metricValue interface{}, expectedType string, metricName string) (err error) {
97-
switch metricValue.(type) {
98-
case float64:
99-
if expectedType != "float" {
100-
err = errors.New("Failed: Field " + metricName + " is not in type " + expectedType)
101-
}
102-
case string:
103-
if expectedType != "string" {
104-
err = errors.New("Failed: Field " + metricName + " is not in type " + expectedType)
105-
}
106-
case int64:
107-
if expectedType != "int" {
108-
err = errors.New("Failed: Field " + metricName + " is not in type " + expectedType)
109-
}
110-
}
111-
return
112-
}

0 commit comments

Comments
 (0)
Please sign in to comment.