Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System test runner MVP #64

Merged
merged 57 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
106cea9
Unexporting const
ycombinator Aug 28, 2020
f26bf88
Fleshing out system test runner a bit
ycombinator Aug 18, 2020
a787cd1
Adding godoc and TODOs
ycombinator Aug 18, 2020
cf2a174
Exporting Ctx
ycombinator Aug 19, 2020
3d85661
Try to boot up test cluster
ycombinator Aug 19, 2020
c527c75
Using logger
ycombinator Aug 20, 2020
05c7487
WIP
ycombinator Aug 21, 2020
3ecb0d4
WIP: rename service to servicedeployer
ycombinator Aug 21, 2020
8d86523
WIP: start talking to Kibana APIs
ycombinator Aug 21, 2020
3d34177
Fixing compile errors
ycombinator Aug 21, 2020
8508671
Delete policy when test ends
ycombinator Aug 22, 2020
07a0d35
WIP: Adding idea TODOs
ycombinator Aug 25, 2020
44acacf
More WIP TODO
ycombinator Aug 25, 2020
1c5491b
Fixing syntax error
ycombinator Aug 25, 2020
1cdb3c3
WIP: Fleshing out Kibana API call for adding package to policy
ycombinator Aug 25, 2020
f28f6c5
Fixing compile errors
ycombinator Aug 25, 2020
f5e7716
WIP: call Kibana API to add datastream to policy
ycombinator Aug 25, 2020
c9401e6
Allow for scalar or list var types
ycombinator Aug 26, 2020
4529add
Add elastic-agent serice to snapshot docker-compose file
ycombinator Aug 26, 2020
ec78efe
Adding healthcheck for elastic-agent service
ycombinator Aug 26, 2020
325334e
Adding methods to assign policy to agent
ycombinator Aug 26, 2020
78fffdc
Reassign agent to original policy so test policy can be cleaned up
ycombinator Aug 26, 2020
133070c
Overlay test config vars
ycombinator Aug 26, 2020
a9830f2
WIP: mounting hackery in progress
ycombinator Aug 28, 2020
762bf8b
Fixing rebase errors
ycombinator Aug 31, 2020
756437b
Fleshing out docker-compose service deployer
ycombinator Sep 1, 2020
8d6f13a
Adding bind mount for temp dir in agent container
ycombinator Sep 1, 2020
e9e2ae5
Adding TODO + debug log for ctxt
ycombinator Sep 1, 2020
c7d7eb5
Using consts for log file names
ycombinator Sep 1, 2020
602079b
Creating function stub and moving TODO
ycombinator Sep 1, 2020
173db44
Apply context to config
ycombinator Sep 1, 2020
84e1bec
Updating fleet ES URL in Kibana config
ycombinator Sep 1, 2020
240cbc7
Add Service.Hostname context var
ycombinator Sep 1, 2020
2c209bd
Wait until true
ycombinator Sep 1, 2020
7307381
Update root service in dependency tree
ycombinator Sep 1, 2020
cb87e8f
Renaming per feedback
ycombinator Sep 1, 2020
f24d666
Move STDOUT/STDERR cleanup to defers
ycombinator Sep 1, 2020
f4b0b26
Consistent naming
ycombinator Sep 1, 2020
38c62ae
Adding godoc explaining context
ycombinator Sep 1, 2020
fcae0b7
Breaking up ServiceRunner into ServiceDeployer and DeployedService in…
ycombinator Sep 1, 2020
c0c672a
Strictly type context
ycombinator Sep 1, 2020
7ee7bd9
Sharing ES client across test runs
ycombinator Sep 1, 2020
b4a63e7
Renaming files to be consistent across test runners
ycombinator Sep 1, 2020
70427df
Adding some godoc + unexporting unnecessary exports
ycombinator Sep 1, 2020
6583bdc
Adding godoc
ycombinator Sep 1, 2020
1ab1ab5
Adding license headers
ycombinator Sep 1, 2020
fcec6d1
Changing local dir to /tmp/service_logs
ycombinator Sep 1, 2020
65bf419
Moving service context to servicedeployer package
ycombinator Sep 8, 2020
99c3f4a
Read ES and Kibana hostnames from Elastic Stack Docker Compose config…
ycombinator Sep 8, 2020
9fde2df
Adding test timestamp to policy name
ycombinator Sep 8, 2020
326120e
Bumping up default version of Elastic Stack to latest released version
ycombinator Sep 8, 2020
8c1c071
Renaming method per language idiom
ycombinator Sep 8, 2020
870e3bd
Fixing comment that I missed earlier
ycombinator Sep 8, 2020
1fccf0e
Prefixing shellinit hostnames with http://
ycombinator Sep 8, 2020
e0f21d7
Refactoring: introducing dockerComposeOptions struct
ycombinator Sep 8, 2020
8c56b7a
Bumping up default stack version to 7.10.0-SNAPSHOT
ycombinator Sep 8, 2020
d1886e7
Updating health check command for Elastic Agent
ycombinator Sep 9, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions cmd/testrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/spf13/cobra"

"github.com/elastic/elastic-package/internal/cobraext"
"github.com/elastic/elastic-package/internal/elasticsearch"
"github.com/elastic/elastic-package/internal/packages"
"github.com/elastic/elastic-package/internal/testrunner"
_ "github.com/elastic/elastic-package/internal/testrunner/runners" // register all test runners
Expand Down Expand Up @@ -82,22 +83,29 @@ func testTypeCommandActionFactory(testType testrunner.TestType) cobraext.Command
return errors.Wrap(err, "locating package root failed")
}

testFolderPaths, err := testrunner.FindTestFolders(packageRootPath, testType, datasets)
testFolders, err := testrunner.FindTestFolders(packageRootPath, testType, datasets)
if err != nil {
return errors.Wrap(err, "unable to determine test folder paths")
}

if failOnMissing && len(testFolderPaths) == 0 {
if failOnMissing && len(testFolders) == 0 {
if len(datasets) > 0 {
return fmt.Errorf("no %s tests found for %s dataset(s)", testType, strings.Join(datasets, ","))
}
return fmt.Errorf("no %s tests found", testType)
}

for _, path := range testFolderPaths {
esClient, err := elasticsearch.Client()
if err != nil {
return errors.Wrap(err, "fetching Elasticsearch client instance failed")
}

for _, folder := range testFolders {
if err := testrunner.Run(testType, testrunner.TestOptions{
TestFolderPath: path,
TestFolder: folder,
PackageRootPath: packageRootPath,
GenerateTestResult: generateTestResult,
ESClient: esClient,
}); err != nil {
return errors.Wrapf(err, "error running package %s tests", testType)
}
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.14
require (
github.com/AlecAivazis/survey/v2 v2.1.0
github.com/Masterminds/semver v1.5.0
github.com/aymerick/raymond v2.0.2+incompatible
github.com/elastic/go-elasticsearch/v7 v7.9.0
github.com/elastic/package-spec/code/go v0.0.0-20200826192647-f45b05c887b5
github.com/go-git/go-billy/v5 v5.0.0
Expand All @@ -14,7 +15,10 @@ require (
github.com/magefile/mage v1.10.0
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.0.0
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de // indirect
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20200817155316-9781c653f443 // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
)
9 changes: 8 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
Expand Down Expand Up @@ -189,6 +191,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
Expand All @@ -206,7 +210,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
Expand All @@ -230,9 +233,13 @@ golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200817155316-9781c653f443 h1:X18bCaipMcoJGm27Nv7zr4XYPKGUy92GtqboKC2Hxaw=
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
10 changes: 6 additions & 4 deletions internal/builder/dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"path/filepath"

"github.com/pkg/errors"

"github.com/elastic/elastic-package/internal/common"
)

var fieldsToEncode = []string{
Expand Down Expand Up @@ -53,15 +55,15 @@ func encodeDashboards(destinationDir string) error {
// The reason is that for versioning it is much nicer to have the full
// json so only on packaging this is changed.
func encodedSavedObject(data []byte) ([]byte, bool, error) {
savedObject := mapStr{}
savedObject := common.MapStr{}
err := json.Unmarshal(data, &savedObject)
if err != nil {
return nil, false, errors.Wrapf(err, "unmarshalling saved object failed")
}

var changed bool
for _, v := range fieldsToEncode {
out, err := savedObject.getValue(v)
out, err := savedObject.GetValue(v)
// This means the key did not exists, no conversion needed.
if err != nil {
continue
Expand All @@ -79,11 +81,11 @@ func encodedSavedObject(data []byte) ([]byte, bool, error) {
if err != nil {
return nil, false, err
}
_, err = savedObject.put(v, string(r))
_, err = savedObject.Put(v, string(r))
if err != nil {
return nil, false, errors.Wrapf(err, "can't put value to the saved object")
}
changed = true
}
return []byte(savedObject.stringToPrint()), changed, nil
return []byte(savedObject.StringToPrint()), changed, nil
}
38 changes: 19 additions & 19 deletions internal/builder/mapstr.go → internal/common/mapstr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package builder
package common

// WARNING: This code is copied from https://github.com/elastic/beats/blob/master/libbeat/common/mapstr.go
// This was done to not have to import the full common package and all its dependencies
Expand All @@ -21,13 +21,13 @@ var (
errKeyNotFound = errors.New("key not found")
)

// mapStr is a map[string]interface{} wrapper with utility methods for common
// MapStr is a map[string]interface{} wrapper with utility methods for common
// map operations like converting to JSON.
type mapStr map[string]interface{}
type MapStr map[string]interface{}

// GetValue gets a value from the map. If the key does not exist then an error
// is returned.
func (m mapStr) getValue(key string) (interface{}, error) {
func (m MapStr) GetValue(key string) (interface{}, error) {
_, _, v, found, err := mapFind(key, m, false)
if err != nil {
return nil, err
Expand All @@ -45,7 +45,7 @@ func (m mapStr) getValue(key string) (interface{}, error) {
//
// If you need insert keys containing dots then you must use bracket notation
// to insert values (e.g. m[key] = value).
func (m mapStr) put(key string, value interface{}) (interface{}, error) {
func (m MapStr) Put(key string, value interface{}) (interface{}, error) {
// XXX `safemapstr.Put` mimics this implementation, both should be updated to have similar behavior
k, d, old, _, err := mapFind(key, m, true)
if err != nil {
Expand All @@ -56,38 +56,38 @@ func (m mapStr) put(key string, value interface{}) (interface{}, error) {
return old, nil
}

// StringToPrint returns the mapStr as pretty JSON.
func (m mapStr) stringToPrint() string {
json, err := json.MarshalIndent(m, "", " ")
// StringToPrint returns the MapStr as pretty JSON.
func (m MapStr) StringToPrint() string {
j, err := json.MarshalIndent(m, "", " ")
if err != nil {
return fmt.Sprintf("Not valid json: %v", err)
}
return string(json)
return string(j)
}

// tomapStr performs a type assertion on v and returns a mapStr. v can be either
// a mapStr or a map[string]interface{}. If it's any other type or nil then
// tomapStr performs a type assertion on v and returns a MapStr. v can be either
// a MapStr or a map[string]interface{}. If it's any other type or nil then
// an error is returned.
func toMapStr(v interface{}) (mapStr, error) {
func toMapStr(v interface{}) (MapStr, error) {
m, ok := tryToMapStr(v)
if !ok {
return nil, errors.Errorf("expected map but type is %T", v)
}
return m, nil
}

func tryToMapStr(v interface{}) (mapStr, bool) {
func tryToMapStr(v interface{}) (MapStr, bool) {
switch m := v.(type) {
case mapStr:
case MapStr:
return m, true
case map[string]interface{}:
return mapStr(m), true
return MapStr(m), true
default:
return nil, false
}
}

// mapFind iterates a mapStr based on a the given dotted key, finding the final
// mapFind iterates a MapStr based on a the given dotted key, finding the final
// subMap and subKey to operate on.
// An error is returned if some intermediate is no map or the key doesn't exist.
// If createMissing is set to true, intermediate maps are created.
Expand All @@ -97,9 +97,9 @@ func tryToMapStr(v interface{}) (mapStr, bool) {
// the original value.
func mapFind(
key string,
data mapStr,
data MapStr,
createMissing bool,
) (subKey string, subMap mapStr, oldValue interface{}, present bool, err error) {
) (subKey string, subMap MapStr, oldValue interface{}, present bool, err error) {
// XXX `safemapstr.mapFind` mimics this implementation, both should be updated to have similar behavior

for {
Expand All @@ -117,7 +117,7 @@ func mapFind(
d, exists := data[k]
if !exists {
if createMissing {
d = mapStr{}
d = MapStr{}
data[k] = d
} else {
return "", nil, nil, false, errKeyNotFound
Expand Down
Loading