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] Move JSON tests from python->go #27816

Merged
merged 2 commits into from
Sep 8, 2021
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
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