Skip to content

Commit 3c02bcd

Browse files
authored
Support system tests otel input (#2885)
This PR enables to run system tests also in input packages using the OTEL collector input (otelcol). In order to achieve that the validation process for fields and mappings is currently disabled because we need to determine the specific requirements for validation when the OTEL collector input is configured. * Update index template name * Remove outdated log message * Extract function to create kibana policies * Revert "Extract function to create kibana policies" This reverts commit 77de02ed6bc3c765f8e88954fa3bee5e780ad37a. * Update package datastream - integration policy * Add otel as suffic for dataset * Keep package datastream / integration policy with the previous values * Enable system test for httpcheck package * httpcheck - Added field definitions * httpcheck - replace string by keyword type * Update comments * Skip some OTEL fields - to be validated * Update index template and data stream names for system tests * Skip validation per fields in OTEL collector input * Remove skip fields for OTEL Packages using OTEL collector input will perform the validation based on the mappings found before and after ingesting documents. * Skip dynamic templates without match condition * Replace stringInArray * Validate dataset fields also in OTEL * Remove duplicated assignment * Remove unnecessary else block * Add warning message * Update test package * Add OTEL option when validating fields in transform * Remove all field definitions * Restore base-fields field definitions * Remove skip test
1 parent e63cf67 commit 3c02bcd

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

internal/fields/validate.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ type Validator struct {
154154

155155
disabledNormalization bool
156156

157+
enabledOTELValidation bool
158+
157159
injectFieldsOptions InjectFieldsOptions
158160
}
159161

@@ -246,6 +248,14 @@ func WithInjectFieldsOptions(options InjectFieldsOptions) ValidatorOption {
246248
}
247249
}
248250

251+
// WithOTELValidation configures the validator to enable or disable OpenTelemetry specific validation.
252+
func WithOTELValidation(otelValidation bool) ValidatorOption {
253+
return func(v *Validator) error {
254+
v.enabledOTELValidation = otelValidation
255+
return nil
256+
}
257+
}
258+
249259
type packageRootFinder interface {
250260
FindPackageRoot() (string, bool, error)
251261
}
@@ -559,7 +569,13 @@ func (v *Validator) ValidateDocumentBody(body json.RawMessage) multierror.Error
559569
// ValidateDocumentMap validates the provided document as common.MapStr.
560570
func (v *Validator) ValidateDocumentMap(body common.MapStr) multierror.Error {
561571
errs := v.validateDocumentValues(body)
562-
errs = append(errs, v.validateMapElement("", body, body)...)
572+
573+
// If package uses OpenTelemetry Collector, skip field validation and just
574+
// validate document values (datasets).
575+
if !v.enabledOTELValidation {
576+
errs = append(errs, v.validateMapElement("", body, body)...)
577+
}
578+
563579
if len(errs) == 0 {
564580
return nil
565581
}
@@ -602,7 +618,7 @@ func (v *Validator) validateDocumentValues(body common.MapStr) multierror.Error
602618
}
603619

604620
str, ok := valueToString(value, v.disabledNormalization)
605-
exists := stringInArray(str, renderedExpectedDatasets)
621+
exists := slices.Contains(renderedExpectedDatasets, str)
606622
if !ok || !exists {
607623
err := fmt.Errorf("field %q should have value in %q, it has \"%v\"",
608624
datasetField, v.expectedDatasets, value)
@@ -613,18 +629,6 @@ func (v *Validator) validateDocumentValues(body common.MapStr) multierror.Error
613629
return errs
614630
}
615631

616-
func stringInArray(target string, arr []string) bool {
617-
// Check if target is part of the array
618-
found := false
619-
for _, item := range arr {
620-
if item == target {
621-
found = true
622-
break
623-
}
624-
}
625-
return found
626-
}
627-
628632
func valueToString(value any, disabledNormalization bool) (string, bool) {
629633
if disabledNormalization {
630634
// when synthetics mode is enabled, each field present in the document is an array

internal/testrunner/runners/system/tester.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ var (
145145
type fieldValidationMethod int
146146

147147
const (
148+
// Required to allow setting `fields` as an option via environment variable
148149
fieldsMethod fieldValidationMethod = iota
149150
mappingsMethod
150151
)
@@ -1616,19 +1617,25 @@ func (r *tester) waitForDocs(ctx context.Context, config *testConfig, dataStream
16161617
}
16171618

16181619
func (r *tester) validateTestScenario(ctx context.Context, result *testrunner.ResultComposer, scenario *scenarioTest, config *testConfig) ([]testrunner.TestResult, error) {
1620+
logger.Info("Validating test case...")
16191621
expectedDatasets, err := r.expectedDatasets(scenario, config)
16201622
if err != nil {
16211623
return nil, err
16221624
}
16231625

1624-
// Validate fields in docs
1626+
if r.isTestUsingOTELCollectorInput(scenario.policyTemplateInput) {
1627+
logger.Warn("Validation for packages using OpenTelemetry Collector input is experimental")
1628+
}
1629+
16251630
fieldsValidator, err := fields.CreateValidatorForDirectory(r.dataStreamPath,
16261631
fields.WithSpecVersion(r.pkgManifest.SpecVersion),
16271632
fields.WithNumericKeywordFields(config.NumericKeywordFields),
16281633
fields.WithStringNumberFields(config.StringNumberFields),
16291634
fields.WithExpectedDatasets(expectedDatasets),
16301635
fields.WithEnabledImportAllECSSChema(true),
16311636
fields.WithDisableNormalization(scenario.syntheticEnabled),
1637+
// When using the OTEL collector input, just a subset of validations are performed (e.g. check expected datasets)
1638+
fields.WithOTELValidation(r.isTestUsingOTELCollectorInput(scenario.policyTemplateInput)),
16321639
)
16331640
if err != nil {
16341641
return result.WithErrorf("creating fields validator for data stream failed (path: %s): %w", r.dataStreamPath, err)
@@ -1641,7 +1648,7 @@ func (r *tester) validateTestScenario(ctx context.Context, result *testrunner.Re
16411648
})
16421649
}
16431650

1644-
if r.fieldValidationMethod == mappingsMethod {
1651+
if !r.isTestUsingOTELCollectorInput(scenario.policyTemplateInput) && r.fieldValidationMethod == mappingsMethod {
16451652
logger.Debug("Performing validation based on mappings")
16461653
exceptionFields := listExceptionFields(scenario.docs, fieldsValidator)
16471654

@@ -1698,7 +1705,7 @@ func (r *tester) validateTestScenario(ctx context.Context, result *testrunner.Re
16981705
}
16991706

17001707
// Check transforms if present
1701-
if err := r.checkTransforms(ctx, config, r.pkgManifest, scenario.dataStream, scenario.syntheticEnabled); err != nil {
1708+
if err := r.checkTransforms(ctx, config, r.pkgManifest, scenario.dataStream, scenario.policyTemplateInput, scenario.syntheticEnabled); err != nil {
17021709
results, _ := result.WithError(err)
17031710
return results, nil
17041711
}
@@ -1817,6 +1824,19 @@ func (r *tester) runTest(ctx context.Context, config *testConfig, stackConfig st
18171824
return r.validateTestScenario(ctx, result, scenario, config)
18181825
}
18191826

1827+
func (r *tester) isTestUsingOTELCollectorInput(policyTemplateInput string) bool {
1828+
// Just supported for input packages currently
1829+
if r.pkgManifest.Type != "input" {
1830+
return false
1831+
}
1832+
1833+
if policyTemplateInput != otelCollectorInputName {
1834+
return false
1835+
}
1836+
1837+
return true
1838+
}
1839+
18201840
func dumpScenarioDocs(docs any) error {
18211841
timestamp := time.Now().Format("20060102150405")
18221842
path := filepath.Join(os.TempDir(), fmt.Sprintf("elastic-package-test-docs-dump-%s.json", timestamp))
@@ -1983,16 +2003,14 @@ func createInputPackageDatastream(
19832003
PolicyTemplate: policyTemplate.Name,
19842004
Enabled: true,
19852005
Vars: kibana.Vars{},
2006+
Type: policyTemplate.Input,
19862007
},
19872008
}
19882009

1989-
streamInput := policyTemplate.Input
1990-
r.Inputs[0].Type = streamInput
1991-
19922010
dataset := fmt.Sprintf("%s.%s", pkg.Name, policyTemplate.Name)
19932011
streams := []kibana.Stream{
19942012
{
1995-
ID: fmt.Sprintf("%s-%s.%s", streamInput, pkg.Name, policyTemplate.Name),
2013+
ID: fmt.Sprintf("%s-%s.%s", policyTemplate.Input, pkg.Name, policyTemplate.Name),
19962014
Enabled: true,
19972015
DataStream: kibana.DataStream{
19982016
Type: policyTemplate.Type,
@@ -2145,7 +2163,7 @@ func selectPolicyTemplateByName(policies []packages.PolicyTemplate, name string)
21452163
return packages.PolicyTemplate{}, fmt.Errorf("policy template %q not found", name)
21462164
}
21472165

2148-
func (r *tester) checkTransforms(ctx context.Context, config *testConfig, pkgManifest *packages.PackageManifest, dataStream string, syntheticEnabled bool) error {
2166+
func (r *tester) checkTransforms(ctx context.Context, config *testConfig, pkgManifest *packages.PackageManifest, dataStream, policyTemplateInput string, syntheticEnabled bool) error {
21492167
if config.SkipTransformValidation {
21502168
return nil
21512169
}
@@ -2199,6 +2217,8 @@ func (r *tester) checkTransforms(ctx context.Context, config *testConfig, pkgMan
21992217
fields.WithNumericKeywordFields(config.NumericKeywordFields),
22002218
fields.WithEnabledImportAllECSSChema(true),
22012219
fields.WithDisableNormalization(syntheticEnabled),
2220+
// When using the OTEL collector input, just a subset of validations are performed (e.g. check expected datasets)
2221+
fields.WithOTELValidation(r.isTestUsingOTELCollectorInput(policyTemplateInput)),
22022222
)
22032223
if err != nil {
22042224
return fmt.Errorf("creating fields validator for data stream failed (path: %s): %w", transformRootPath, err)
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
skip:
2-
reason: Not supported system tests with input type otelcol.
3-
link: https://github.com/elastic/elastic-package/issues/2835
41
service: web
52
vars:
63
period: 1s
74
endpoints:
85
- http://{{Hostname}}:{{Port}}
6+
assert:
7+
min_count: 150

0 commit comments

Comments
 (0)