Skip to content

Commit

Permalink
[Heartbeat] Move JSON tests from python->go (elastic#27816)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewvc authored and wiwen committed Nov 1, 2021
1 parent fdd2147 commit 8916f35
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 82 deletions.
9 changes: 9 additions & 0 deletions heartbeat/hbtest/hbtestutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ func SizedResponseHandler(bytes int) http.HandlerFunc {
)
}

func CustomResponseHandler(body []byte, status int) http.HandlerFunc {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(status)
w.Write(body)
},
)
}

// RedirectHandler redirects the paths at the keys in the redirectingPaths map to the locations in their values.
// For paths not in the redirectingPaths map it returns a 200 response with the given body.
func RedirectHandler(redirectingPaths map[string]string, body string) http.HandlerFunc {
Expand Down
106 changes: 106 additions & 0 deletions heartbeat/monitors/active/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,112 @@ func TestLargeResponse(t *testing.T) {
)
}

func TestJsonBody(t *testing.T) {
type testCase struct {
name string
responseBody string
condition common.MapStr
expectedErrMsg string
expectedContentType string
}

testCases := []testCase{
{
"simple match",
"{\"foo\": \"bar\"}",
common.MapStr{
"equals": common.MapStr{"foo": "bar"},
},
"",
"application/json",
},
{
"mismatch",
"{\"foo\": \"bar\"}",
common.MapStr{
"equals": common.MapStr{"baz": "bot"},
},
"JSON body did not match",
"application/json",
},
{
"invalid json",
"notjson",
common.MapStr{
"equals": common.MapStr{"foo": "bar"},
},
"could not parse JSON",
"text/plain; charset=utf-8",
},
{
"complex type match json",
"{\"number\": 3, \"bool\": true}",
common.MapStr{
"equals": common.MapStr{"number": 3, "bool": true},
},
"",
"application/json",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
server := httptest.NewServer(hbtest.CustomResponseHandler([]byte(tc.responseBody), 200))
defer server.Close()

configSrc := map[string]interface{}{
"hosts": server.URL,
"timeout": "1s",
"response.include_body": "never",
"check.response.json": []common.MapStr{
{
"description": "myJsonCheck",
"condition": tc.condition,
},
},
}

config, err := common.NewConfigFrom(configSrc)
require.NoError(t, err)

p, err := create("largeresp", config)
require.NoError(t, err)

sched, _ := schedule.Parse("@every 1s")
job := wrappers.WrapCommon(p.Jobs, stdfields.StdMonitorFields{ID: "test", Type: "http", Schedule: sched, Timeout: 1})[0]

event := &beat.Event{}
_, err = job(event)
require.NoError(t, err)

if tc.expectedErrMsg == "" {
testslike.Test(
t,
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "up", "http"),
hbtest.RespondingTCPChecks(),
hbtest.SummaryChecks(1, 0),
respondingHTTPChecks(server.URL, tc.expectedContentType, 200),
)),
event.Fields,
)
} else {
testslike.Test(
t,
lookslike.Strict(lookslike.Compose(
hbtest.BaseChecks("127.0.0.1", "down", "http"),
hbtest.RespondingTCPChecks(),
hbtest.SummaryChecks(0, 1),
hbtest.ErrorChecks(tc.expectedErrMsg, "validate"),
respondingHTTPChecks(server.URL, tc.expectedContentType, 200),
)),
event.Fields,
)
}
})
}
}

func runHTTPSServerCheck(
t *testing.T,
server *httptest.Server,
Expand Down
82 changes: 0 additions & 82 deletions heartbeat/tests/system/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,88 +90,6 @@ def test_http_delayed(self):
finally:
server.shutdown()

@parameterized.expand([
("up", '{"foo": {"baz": "bar"}}'),
("down", '{"foo": "unexpected"}'),
("down", 'notjson'),
])
def test_http_json(self, expected_status, body):
"""
Test JSON response checks
"""
server = self.start_server(body, 200)
try:
self.render_config_template(
monitors=[{
"type": "http",
"urls": ["http://localhost:{}".format(server.server_port)],
"check_response_json": [{
"description": "foo equals bar",
"condition": {
"equals": {"foo": {"baz": "bar"}}
}
}]
}]
)

try:
proc = self.start_beat()
self.wait_until(lambda: self.log_contains("heartbeat is running"))

self.wait_until(
lambda: self.output_has(lines=1))
finally:
proc.check_kill_and_wait()

self.assert_last_status(expected_status)
if expected_status == "down":
self.assertEqual(self.last_output_line()["http.response.body.content"], body)
if body == "notjson":
self.assertEqual(self.last_output_line()["http.response.mime_type"], "text/plain; charset=utf-8")
else:
self.assertEqual(self.last_output_line()["http.response.mime_type"], "application/json")
else:
assert "http.response.body.content" not in self.last_output_line()
finally:
server.shutdown()

@parameterized.expand([
('{"foo": "bar"}', {"foo": "bar"}),
('{"foo": true}', {"foo": True},),
('{"foo": 3}', {"foo": 3},),
])
def test_json_simple_comparisons(self, body, comparison):
"""
Test JSON response with simple straight-forward comparisons
"""
server = self.start_server(body, 200)
try:
self.render_config_template(
monitors=[{
"type": "http",
"urls": ["http://localhost:{}".format(server.server_port)],
"check_response_json": [{
"description": body,
"condition": {
"equals": comparison
}
}]
}]
)

try:
proc = self.start_beat()
self.wait_until(lambda: self.log_contains("heartbeat is running"))

self.wait_until(
lambda: self.output_has(lines=1))
finally:
proc.check_kill_and_wait()

self.assert_last_status("up")
finally:
server.shutdown()

@parameterized.expand([
(lambda server: "localhost:{}".format(server.server_port), "up"),
# This IP is reserved in IPv4
Expand Down

0 comments on commit 8916f35

Please sign in to comment.