Skip to content

Commit 86360ba

Browse files
authored
Add ability to skip tests (#221)
* Adding skipped to reporters * Adding skipped to pipeline test runner * Adding skipped to system test runner * Adding skipped field to test result * Add skip configuration for asset loading tests * Refactoring: extracting result composer for reuse in multiple packages * Use result composer in asset loading test runner * Adding godoc * Refactoring: extract skip config struct * Adding license header + struct godoc * Account for no test config * Fix error message * Adding skip section to test package * Add warning logs for skipped tests * Include test result * Stringify link * Using result * Fixing format * Make skipped optional * Add skip reason and link * Introducing SkippableConfig * Introducing constructor for ResultComposer * Temporarily commenting out skip so test runs again * Making test fail with bad path * Putting back skip section
1 parent dcebdb3 commit 86360ba

File tree

11 files changed

+253
-99
lines changed

11 files changed

+253
-99
lines changed

internal/testrunner/reporters/formats/human.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ func reportHumanFormat(results []testrunner.TestResult) (string, error) {
3636
result = fmt.Sprintf("ERROR: %s", r.ErrorMsg)
3737
} else if r.FailureMsg != "" {
3838
result = fmt.Sprintf("FAIL: %s", r.FailureMsg)
39+
} else if r.Skipped != nil {
40+
result = r.Skipped.String()
3941
} else {
4042
result = "PASS"
4143
}

internal/testrunner/reporters/formats/xunit.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type testSuite struct {
3333
NumTests int `xml:"tests,attr,omitempty"`
3434
NumFailures int `xml:"failures,attr,omitempty"`
3535
NumErrors int `xml:"errors,attr,omitempty"`
36+
NumSkipped int `xml:"skipped,attr,omitempty"`
3637

3738
Suites []testSuite `xml:"testsuite,omitempty"`
3839
Cases []testCase `xml:"testcase,omitempty"`
@@ -42,15 +43,20 @@ type testCase struct {
4243
ClassName string `xml:"classname,attr"`
4344
TimeInSeconds float64 `xml:"time,attr"`
4445

45-
Error string `xml:"error,omitempty"`
46-
Failure string `xml:"failure,omitempty"`
46+
Error string `xml:"error,omitempty"`
47+
Failure string `xml:"failure,omitempty"`
48+
Skipped *skipped `xml:"skipped,omitempty"`
49+
}
50+
51+
type skipped struct {
52+
Message string `xml:"message,attr"`
4753
}
4854

4955
func reportXUnitFormat(results []testrunner.TestResult) (string, error) {
5056
// test type => package => data stream => test cases
5157
tests := map[string]map[string]map[string][]testCase{}
5258

53-
var numTests, numFailures, numErrors int
59+
var numTests, numFailures, numErrors, numSkipped int
5460
for _, r := range results {
5561
testType := string(r.TestType)
5662
if _, exists := tests[testType]; !exists {
@@ -79,6 +85,10 @@ func reportXUnitFormat(results []testrunner.TestResult) (string, error) {
7985
numErrors++
8086
}
8187

88+
if r.Skipped != nil {
89+
numSkipped++
90+
}
91+
8292
name := fmt.Sprintf("%s test", r.TestType)
8393
if r.Name != "" {
8494
name += ": " + r.Name
@@ -91,6 +101,11 @@ func reportXUnitFormat(results []testrunner.TestResult) (string, error) {
91101
Error: r.ErrorMsg,
92102
Failure: failure,
93103
}
104+
105+
if r.Skipped != nil {
106+
c.Skipped = &skipped{r.Skipped.String()}
107+
}
108+
94109
numTests++
95110

96111
tests[testType][r.Package][r.DataStream] = append(tests[testType][r.Package][r.DataStream], c)
@@ -107,6 +122,7 @@ func reportXUnitFormat(results []testrunner.TestResult) (string, error) {
107122
NumTests: numTests,
108123
NumFailures: numFailures,
109124
NumErrors: numErrors,
125+
NumSkipped: numSkipped,
110126

111127
Cases: make([]testCase, 0),
112128
}

internal/testrunner/runners/asset/runner.go

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99
"path/filepath"
1010
"strings"
11-
"time"
1211

1312
es "github.com/elastic/go-elasticsearch/v7"
1413
"github.com/pkg/errors"
@@ -63,43 +62,39 @@ func (r runner) Run(options testrunner.TestOptions) ([]testrunner.TestResult, er
6362
}
6463

6564
func (r *runner) run() ([]testrunner.TestResult, error) {
66-
result := testrunner.TestResult{
65+
result := testrunner.NewResultComposer(testrunner.TestResult{
6766
TestType: TestType,
6867
Package: r.testFolder.Package,
69-
}
68+
})
7069

71-
startTime := time.Now()
72-
resultsWith := func(tr testrunner.TestResult, err error) ([]testrunner.TestResult, error) {
73-
tr.TimeElapsed = time.Now().Sub(startTime)
74-
if err == nil {
75-
return []testrunner.TestResult{tr}, nil
76-
}
70+
testConfig, err := newConfig(r.testFolder.Path)
71+
if err != nil {
72+
return result.WithError(errors.Wrap(err, "unable to load asset loading test config file"))
7773

78-
if tcf, ok := err.(testrunner.ErrTestCaseFailed); ok {
79-
tr.FailureMsg = tcf.Reason
80-
tr.FailureDetails = tcf.Details
81-
return []testrunner.TestResult{tr}, nil
82-
}
74+
}
8375

84-
tr.ErrorMsg = err.Error()
85-
return []testrunner.TestResult{tr}, err
76+
if testConfig != nil && testConfig.Skip != nil {
77+
logger.Warnf("skipping %s test for %s: %s (details: %s)",
78+
TestType, r.testFolder.Package,
79+
testConfig.Skip.Reason, testConfig.Skip.Link.String())
80+
return result.WithSkip(testConfig.Skip)
8681
}
8782

8883
pkgManifest, err := packages.ReadPackageManifest(filepath.Join(r.packageRootPath, packages.PackageManifestFile))
8984
if err != nil {
90-
return resultsWith(result, errors.Wrap(err, "reading package manifest failed"))
85+
return result.WithError(errors.Wrap(err, "reading package manifest failed"))
9186
}
9287

9388
// Install package
9489
kib, err := kibana.NewClient()
9590
if err != nil {
96-
return resultsWith(result, errors.Wrap(err, "could not create kibana client"))
91+
return result.WithError(errors.Wrap(err, "could not create kibana client"))
9792
}
9893

9994
logger.Debug("installing package...")
10095
actualAssets, err := kib.InstallPackage(*pkgManifest)
10196
if err != nil {
102-
return resultsWith(result, errors.Wrap(err, "could not install package"))
97+
return result.WithError(errors.Wrap(err, "could not install package"))
10398
}
10499
r.removePackageHandler = func() error {
105100
logger.Debug("removing package...")
@@ -111,26 +106,29 @@ func (r *runner) run() ([]testrunner.TestResult, error) {
111106

112107
expectedAssets, err := packages.LoadPackageAssets(r.packageRootPath)
113108
if err != nil {
114-
return resultsWith(result, errors.Wrap(err, "could not load expected package assets"))
109+
return result.WithError(errors.Wrap(err, "could not load expected package assets"))
115110
}
116111

117112
results := make([]testrunner.TestResult, 0, len(expectedAssets))
118113
for _, e := range expectedAssets {
119-
result := testrunner.TestResult{
120-
Name: fmt.Sprintf("%s %s is loaded", e.Type, e.ID),
121-
Package: pkgManifest.Name,
122-
DataStream: e.DataStream,
123-
TestType: TestType,
124-
TimeElapsed: time.Now().Sub(startTime),
125-
}
126-
114+
rc := testrunner.NewResultComposer(testrunner.TestResult{
115+
Name: fmt.Sprintf("%s %s is loaded", e.Type, e.ID),
116+
Package: pkgManifest.Name,
117+
DataStream: e.DataStream,
118+
TestType: TestType,
119+
})
120+
121+
var r []testrunner.TestResult
127122
if !findActualAsset(actualAssets, e) {
128-
result.FailureMsg = "could not find expected asset"
129-
result.FailureDetails = fmt.Sprintf("could not find %s asset \"%s\". Assets loaded:\n%s", e.Type, e.ID, formatAssetsAsString(actualAssets))
123+
r, _ = rc.WithError(testrunner.ErrTestCaseFailed{
124+
Reason: "could not find expected asset",
125+
Details: fmt.Sprintf("could not find %s asset \"%s\". Assets loaded:\n%s", e.Type, e.ID, formatAssetsAsString(actualAssets)),
126+
})
127+
} else {
128+
r, _ = rc.WithSuccess()
130129
}
131130

132-
results = append(results, result)
133-
startTime = time.Now()
131+
results = append(results, r[0])
134132
}
135133

136134
return results, nil
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License;
3+
// you may not use this file except in compliance with the Elastic License.
4+
5+
package asset
6+
7+
import (
8+
"io/ioutil"
9+
"os"
10+
"path/filepath"
11+
12+
"github.com/elastic/go-ucfg"
13+
"github.com/elastic/go-ucfg/yaml"
14+
"github.com/pkg/errors"
15+
16+
"github.com/elastic/elastic-package/internal/testrunner"
17+
)
18+
19+
type testConfig struct {
20+
testrunner.SkippableConfig `config:",inline"`
21+
}
22+
23+
func newConfig(assetTestFolderPath string) (*testConfig, error) {
24+
configFilePath := filepath.Join(assetTestFolderPath, "config.yml")
25+
26+
// Test configuration file is optional for asset loading tests. If it
27+
// doesn't exist, we can return early.
28+
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
29+
return nil, nil
30+
}
31+
32+
data, err := ioutil.ReadFile(configFilePath)
33+
if err != nil {
34+
return nil, errors.Wrapf(err, "could not load asset loading test configuration file: %s", configFilePath)
35+
}
36+
37+
var c testConfig
38+
cfg, err := yaml.NewConfig(data, ucfg.PathSep("."))
39+
if err != nil {
40+
return nil, errors.Wrapf(err, "unable to load asset loading test configuration file: %s", configFilePath)
41+
}
42+
if err := cfg.Unpack(&c); err != nil {
43+
return nil, errors.Wrapf(err, "unable to unpack asset loading test configuration file: %s", configFilePath)
44+
}
45+
46+
return &c, nil
47+
}

internal/testrunner/runners/pipeline/runner.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ func (r *runner) run() ([]testrunner.TestResult, error) {
107107
}
108108
tr.Name = tc.name
109109

110+
if tc.config.Skip != nil {
111+
logger.Warnf("skipping %s test for %s/%s: %s (details: %s)",
112+
TestType, r.options.TestFolder.Package, r.options.TestFolder.DataStream,
113+
tc.config.Skip.Reason, tc.config.Skip.Link.String())
114+
115+
tr.Skipped = tc.config.Skip
116+
results = append(results, tr)
117+
continue
118+
}
119+
110120
result, err := simulatePipelineProcessing(r.options.ESClient, entryPipeline, tc)
111121
if err != nil {
112122
err := errors.Wrap(err, "simulating pipeline processing failed")
@@ -170,6 +180,13 @@ func (r *runner) loadTestCaseFile(testCaseFile string) (*testCase, error) {
170180
return nil, errors.Wrapf(err, "reading config for test case failed (testCasePath: %s)", testCasePath)
171181
}
172182

183+
if config.Skip != nil {
184+
return &testCase{
185+
name: testCaseFile,
186+
config: &config,
187+
}, nil
188+
}
189+
173190
ext := filepath.Ext(testCaseFile)
174191

175192
var entries []json.RawMessage

internal/testrunner/runners/pipeline/test_config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ import (
1212
"path/filepath"
1313

1414
"github.com/pkg/errors"
15+
16+
"github.com/elastic/elastic-package/internal/testrunner"
1517
)
1618

1719
const configTestSuffix = "-config.json"
1820

1921
type testConfig struct {
22+
testrunner.SkippableConfig `config:",inline"`
23+
2024
Multiline *multiline `json:"multiline"`
2125
Fields map[string]interface{} `json:"fields"`
2226
DynamicFields map[string]string `json:"dynamic_fields"`

0 commit comments

Comments
 (0)