internal/testrunner/runners/pipeline/runner.go (140 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. package pipeline import ( "context" "fmt" "os" "strings" "time" "github.com/elastic/elastic-package/internal/elasticsearch" "github.com/elastic/elastic-package/internal/packages" "github.com/elastic/elastic-package/internal/profile" "github.com/elastic/elastic-package/internal/testrunner" ) const ( // TestType defining pipeline tests TestType testrunner.TestType = "pipeline" ) type runner struct { packageRootPath string profile *profile.Profile esAPI *elasticsearch.API dataStreams []string failOnMissingTests bool generateTestResult bool withCoverage bool coverageType string deferCleanup time.Duration globalTestConfig testrunner.GlobalRunnerTestConfig } type PipelineTestRunnerOptions struct { Profile *profile.Profile PackageRootPath string API *elasticsearch.API DataStreams []string FailOnMissingTests bool GenerateTestResult bool WithCoverage bool CoverageType string DeferCleanup time.Duration GlobalTestConfig testrunner.GlobalRunnerTestConfig } func NewPipelineTestRunner(options PipelineTestRunnerOptions) *runner { runner := runner{ profile: options.Profile, packageRootPath: options.PackageRootPath, esAPI: options.API, dataStreams: options.DataStreams, failOnMissingTests: options.FailOnMissingTests, generateTestResult: options.GenerateTestResult, withCoverage: options.WithCoverage, coverageType: options.CoverageType, deferCleanup: options.DeferCleanup, globalTestConfig: options.GlobalTestConfig, } return &runner } // Ensures that runner implements testrunner.TestRunner interface var _ testrunner.TestRunner = new(runner) // SetupRunner prepares global resources required by the test runner. func (r *runner) SetupRunner(ctx context.Context) error { return nil } // TearDownRunner cleans up any global test runner resources. It must be called // after the test runner has finished executing all its tests. func (r *runner) TearDownRunner(ctx context.Context) error { return nil } func (r *runner) GetTests(ctx context.Context) ([]testrunner.Tester, error) { var folders []testrunner.TestFolder manifest, err := packages.ReadPackageManifestFromPackageRoot(r.packageRootPath) if err != nil { return nil, fmt.Errorf("reading package manifest failed (path: %s): %w", r.packageRootPath, err) } hasDataStreams, err := testrunner.PackageHasDataStreams(manifest) if err != nil { return nil, fmt.Errorf("cannot determine if package has data streams: %w", err) } if hasDataStreams { var dataStreams []string if len(r.dataStreams) > 0 { dataStreams = r.dataStreams } folders, err = testrunner.FindTestFolders(r.packageRootPath, dataStreams, r.Type()) if err != nil { return nil, fmt.Errorf("unable to determine test folder paths: %w", err) } if r.failOnMissingTests && len(folders) == 0 { if len(dataStreams) > 0 { return nil, fmt.Errorf("no %s tests found for %s data stream(s)", r.Type(), strings.Join(dataStreams, ",")) } return nil, fmt.Errorf("no %s tests found", r.Type()) } } else { folders, err = testrunner.FindTestFolders(r.packageRootPath, nil, r.Type()) if err != nil { return nil, fmt.Errorf("unable to determine test folder paths: %w", err) } if r.failOnMissingTests && len(folders) == 0 { return nil, fmt.Errorf("no %s tests found", r.Type()) } } var testers []testrunner.Tester for _, folder := range folders { testCaseFiles, err := r.listTestCaseFiles(folder) if err != nil { return nil, fmt.Errorf("listing test case definitions failed: %w", err) } for _, caseFile := range testCaseFiles { t, err := NewPipelineTester(PipelineTesterOptions{ TestFolder: folder, PackageRootPath: r.packageRootPath, GenerateTestResult: r.generateTestResult, WithCoverage: r.withCoverage, CoverageType: r.coverageType, DeferCleanup: r.deferCleanup, Profile: r.profile, API: r.esAPI, TestCaseFile: caseFile, GlobalTestConfig: r.globalTestConfig, }) if err != nil { return nil, fmt.Errorf("failed to create pipeline tester: %w", err) } testers = append(testers, t) } } return testers, nil } func (r *runner) Type() testrunner.TestType { return TestType } func (r *runner) listTestCaseFiles(folder testrunner.TestFolder) ([]string, error) { fis, err := os.ReadDir(folder.Path) if err != nil { return nil, fmt.Errorf("reading pipeline tests failed (path: %s): %w", folder.Path, err) } var files []string for _, fi := range fis { if strings.HasSuffix(fi.Name(), expectedTestResultSuffix) || strings.HasSuffix(fi.Name(), configTestSuffixYAML) { continue } files = append(files, fi.Name()) } return files, nil }