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

[Heartbeat] Use go-lookslike instead of mapval for heartbeat tests #12540

Merged
merged 12 commits into from
Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG-developer.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ The list below covers the major changes between 7.0.0-rc2 and master only.
- Only Load minimal template if no fields are provided. {pull}12103[12103]
- Add new option `IgnoreAllErrors` to `libbeat.common.schema` for skipping fields that failed while converting. {pull}12089[12089]
- Deprecate setup cmds for `template` and `ilm-policy`. Add new setup cmd for `index-management`. {pull}12132[12132]
- Use the go-lookslike library for testing in heartbeat. Eventually the mapval package will be replaced with it. {pull}12540[12540]
10 changes: 10 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,16 @@ Copyright 2017-2018 Elasticsearch B.V.
This product includes software developed at
Elasticsearch, B.V. (https://www.elastic.co/).

--------------------------------------------------------------------
Dependency: github.com/elastic/go-lookslike
Version: v0.2.0
Revision: 807124eb9fc6684949aa99744577175fd6bac4fd
License type (autodetected): Apache-2.0
./vendor/github.com/elastic/go-lookslike/LICENSE:
--------------------------------------------------------------------
Apache License 2.0


--------------------------------------------------------------------
Dependency: github.com/elastic/go-lumber
Revision: 616041e345fc33c97bc0eb0fa6b388aa07bca3e1
Expand Down
56 changes: 29 additions & 27 deletions heartbeat/hbtest/hbtestutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ import (
"github.com/stretchr/testify/require"

"github.com/elastic/beats/heartbeat/monitors/wrappers"
"github.com/elastic/beats/libbeat/common/mapval"
"github.com/elastic/beats/libbeat/common/x509util"
"github.com/elastic/go-lookslike"
"github.com/elastic/go-lookslike/isdef"
"github.com/elastic/go-lookslike/validator"
)

// HelloWorldBody is the body of the HelloWorldHandler.
Expand Down Expand Up @@ -85,10 +87,10 @@ func ServerPort(server *httptest.Server) (uint16, error) {
}

// TLSChecks validates the given x509 cert at the given position.
func TLSChecks(chainIndex, certIndex int, certificate *x509.Certificate) mapval.Validator {
return mapval.MustCompile(mapval.Map{
"tls": mapval.Map{
"rtt.handshake.us": mapval.IsDuration,
func TLSChecks(chainIndex, certIndex int, certificate *x509.Certificate) validator.Validator {
return lookslike.MustCompile(map[string]interface{}{
"tls": map[string]interface{}{
"rtt.handshake.us": isdef.IsDuration,
"certificate_not_valid_before": certificate.NotBefore,
"certificate_not_valid_after": certificate.NotAfter,
},
Expand All @@ -98,30 +100,30 @@ func TLSChecks(chainIndex, certIndex int, certificate *x509.Certificate) mapval.
// BaseChecks creates a skima.Validator that represents the "monitor" field present
// in all heartbeat events.
// If IP is set to "" this will check that the field is not present
func BaseChecks(ip string, status string, typ string) mapval.Validator {
var ipCheck mapval.IsDef
func BaseChecks(ip string, status string, typ string) validator.Validator {
var ipCheck isdef.IsDef
if len(ip) > 0 {
ipCheck = mapval.IsEqual(ip)
ipCheck = isdef.IsEqual(ip)
} else {
ipCheck = mapval.Optional(mapval.IsEqual(ip))
ipCheck = isdef.Optional(isdef.IsEqual(ip))
}
return mapval.MustCompile(mapval.Map{
"monitor": mapval.Map{
return lookslike.MustCompile(map[string]interface{}{
"monitor": map[string]interface{}{
"ip": ipCheck,
"duration.us": mapval.IsDuration,
"duration.us": isdef.IsDuration,
"status": status,
"id": mapval.IsNonEmptyString,
"name": mapval.IsString,
"id": isdef.IsNonEmptyString,
"name": isdef.IsString,
"type": typ,
"check_group": mapval.IsString,
"check_group": isdef.IsString,
},
})
}

// SummaryChecks validates the "summary" field and its subfields.
func SummaryChecks(up int, down int) mapval.Validator {
return mapval.MustCompile(mapval.Map{
"summary": mapval.Map{
func SummaryChecks(up int, down int) validator.Validator {
return lookslike.MustCompile(map[string]interface{}{
"summary": map[string]interface{}{
"up": uint16(up),
"down": uint16(down),
},
Expand All @@ -130,7 +132,7 @@ func SummaryChecks(up int, down int) mapval.Validator {

// SimpleURLChecks returns a check for a simple URL
// with only a scheme, host, and port
func SimpleURLChecks(t *testing.T, scheme string, host string, port uint16) mapval.Validator {
func SimpleURLChecks(t *testing.T, scheme string, host string, port uint16) validator.Validator {

hostPort := host
if port != 0 {
Expand All @@ -140,27 +142,27 @@ func SimpleURLChecks(t *testing.T, scheme string, host string, port uint16) mapv
u, err := url.Parse(fmt.Sprintf("%s://%s", scheme, hostPort))
require.NoError(t, err)

return mapval.MustCompile(mapval.Map{
return lookslike.MustCompile(map[string]interface{}{
"url": wrappers.URLFields(u),
})
}

// ErrorChecks checks the standard heartbeat error hierarchy, which should
// consist of a message (or a mapval isdef that can match the message) and a type under the error key.
// consist of a message (or a lookslike isdef that can match the message) and a type under the error key.
// The message is checked only as a substring since exact string matches can be fragile due to platform differences.
func ErrorChecks(msgSubstr string, errType string) mapval.Validator {
return mapval.MustCompile(mapval.Map{
"error": mapval.Map{
"message": mapval.IsStringContaining(msgSubstr),
func ErrorChecks(msgSubstr string, errType string) validator.Validator {
return lookslike.MustCompile(map[string]interface{}{
"error": map[string]interface{}{
"message": isdef.IsStringContaining(msgSubstr),
"type": errType,
},
})
}

// RespondingTCPChecks creates a skima.Validator that represents the "tcp" field present
// in all heartbeat events that use a Tcp connection as part of their DialChain
func RespondingTCPChecks() mapval.Validator {
return mapval.MustCompile(mapval.Map{"tcp.rtt.connect.us": mapval.IsDuration})
func RespondingTCPChecks() validator.Validator {
return lookslike.MustCompile(map[string]interface{}{"tcp.rtt.connect.us": isdef.IsDuration})
}

// CertToTempFile takes a certificate and returns an *os.File with a PEM encoded
Expand Down
51 changes: 27 additions & 24 deletions heartbeat/monitors/active/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ import (
"github.com/elastic/beats/libbeat/beat"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/common/file"
"github.com/elastic/beats/libbeat/common/mapval"
btesting "github.com/elastic/beats/libbeat/testing"
"github.com/elastic/go-lookslike"
"github.com/elastic/go-lookslike/isdef"
"github.com/elastic/go-lookslike/testslike"
"github.com/elastic/go-lookslike/validator"
)

func testRequest(t *testing.T, testURL string) *beat.Event {
Expand Down Expand Up @@ -87,24 +90,24 @@ func checkServer(t *testing.T, handlerFunc http.HandlerFunc) (*httptest.Server,

// The minimum response is just the URL. Only to be used for unreachable server
// tests.
func httpBaseChecks(urlStr string) mapval.Validator {
func httpBaseChecks(urlStr string) validator.Validator {
u, _ := url.Parse(urlStr)
return mapval.MustCompile(mapval.Map{
return lookslike.MustCompile(map[string]interface{}{
"url": wrappers.URLFields(u),
})
}

func respondingHTTPChecks(url string, statusCode int) mapval.Validator {
return mapval.Compose(
func respondingHTTPChecks(url string, statusCode int) validator.Validator {
return lookslike.Compose(
httpBaseChecks(url),
mapval.MustCompile(mapval.Map{
"http": mapval.Map{
lookslike.MustCompile(map[string]interface{}{
"http": map[string]interface{}{
"response.status_code": statusCode,
"rtt.content.us": mapval.IsDuration,
"rtt.response_header.us": mapval.IsDuration,
"rtt.total.us": mapval.IsDuration,
"rtt.validate.us": mapval.IsDuration,
"rtt.write_request.us": mapval.IsDuration,
"rtt.content.us": isdef.IsDuration,
"rtt.response_header.us": isdef.IsDuration,
"rtt.total.us": isdef.IsDuration,
"rtt.validate.us": isdef.IsDuration,
"rtt.write_request.us": isdef.IsDuration,
},
}),
)
Expand Down Expand Up @@ -193,9 +196,9 @@ func TestUpStatuses(t *testing.T) {
t.Run(fmt.Sprintf("Test OK HTTP status %d", status), func(t *testing.T) {
server, event := checkServer(t, hbtest.HelloWorldHandler(status))

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "up", "http"),
hbtest.RespondingTCPChecks(),
hbtest.SummaryChecks(1, 0),
Expand All @@ -213,9 +216,9 @@ func TestDownStatuses(t *testing.T) {
t.Run(fmt.Sprintf("test down status %d", status), func(t *testing.T) {
server, event := checkServer(t, hbtest.HelloWorldHandler(status))

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "down", "http"),
hbtest.RespondingTCPChecks(),
hbtest.SummaryChecks(0, 1),
Expand Down Expand Up @@ -250,9 +253,9 @@ func TestLargeResponse(t *testing.T) {
_, err = job(event)
require.NoError(t, err)

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "up", "http"),
hbtest.RespondingTCPChecks(),
hbtest.SummaryChecks(1, 0),
Expand Down Expand Up @@ -292,9 +295,9 @@ func runHTTPSServerCheck(
time.Sleep(time.Millisecond * 500)
}

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "up", "http"),
hbtest.RespondingTCPChecks(),
hbtest.TLSChecks(0, 0, cert),
Expand Down Expand Up @@ -358,9 +361,9 @@ func TestConnRefusedJob(t *testing.T) {

event := testRequest(t, url)

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks(ip, "down", "http"),
hbtest.SummaryChecks(0, 1),
hbtest.ErrorChecks(url, "io"),
Expand All @@ -380,9 +383,9 @@ func TestUnreachableJob(t *testing.T) {

event := testRequest(t, url)

mapval.Test(
testslike.Test(
t,
mapval.Strict(mapval.Compose(
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks(ip, "down", "http"),
hbtest.SummaryChecks(0, 1),
hbtest.ErrorChecks(url, "io"),
Expand Down
Loading