From 5c455cbe10a40d0925c8448667a59ec2554c69d4 Mon Sep 17 00:00:00 2001 From: tidwall Date: Fri, 23 Sep 2022 17:34:09 -0700 Subject: [PATCH] Better HEALTHZ tests --- internal/server/server.go | 2 +- internal/server/stats.go | 28 ++++++++++++++++++++-------- tests/keys_search_test.go | 2 -- tests/keys_test.go | 33 +++++++++++++++++++++++++++++++++ tests/mock_test.go | 15 +++++++++------ tests/tests_test.go | 21 +++++++++++++++------ 6 files changed, 78 insertions(+), 23 deletions(-) diff --git a/internal/server/server.go b/internal/server/server.go index 0f8d7211..deb764ee 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -1084,7 +1084,7 @@ func (s *Server) command(msg *Message, client *Client) ( case "server": res, err = s.cmdServer(msg) case "healthz": - res, err = s.cmdHealthz(msg) + res, err = s.cmdHEALTHZ(msg) case "info": res, err = s.cmdInfo(msg) case "scan": diff --git a/internal/server/stats.go b/internal/server/stats.go index 4c8dcc4b..0feb361d 100644 --- a/internal/server/stats.go +++ b/internal/server/stats.go @@ -95,22 +95,34 @@ func (s *Server) cmdSTATS(msg *Message) (resp.Value, error) { return resp.ArrayValue(vals), nil } -func (s *Server) cmdHealthz(msg *Message) (res resp.Value, err error) { +// HEALTHZ +func (s *Server) cmdHEALTHZ(msg *Message) (resp.Value, error) { start := time.Now() + + // >> Args + + args := msg.Args + if len(args) != 1 { + return retrerr(errInvalidNumberOfArguments) + } + + // >> Operation + if s.config.followHost() != "" { m := make(map[string]interface{}) s.basicStats(m) if fmt.Sprintf("%v", m["caught_up"]) != "true" { - return NOMessage, errors.New("not caught up") + return retrerr(errors.New("not caught up")) } } - switch msg.OutputType { - case JSON: - res = resp.StringValue(`{"ok":true,"elapsed":"` + time.Since(start).String() + "\"}") - case RESP: - res = resp.SimpleStringValue("OK") + + // >> Response + + if msg.OutputType == JSON { + return resp.StringValue(`{"ok":true,"elapsed":"` + + time.Since(start).String() + "\"}"), nil } - return res, nil + return resp.SimpleStringValue("OK"), nil } func (s *Server) cmdServer(msg *Message) (res resp.Value, err error) { diff --git a/tests/keys_search_test.go b/tests/keys_search_test.go index e68b9236..b3f432e1 100644 --- a/tests/keys_search_test.go +++ b/tests/keys_search_test.go @@ -122,9 +122,7 @@ func keys_KNN_random_test(mc *mockServer) error { mc.Do("OUTPUT", "json") defer mc.Do("OUTPUT", "resp") - start := time.Now() res, err := redis.String(mc.Do("NEARBY", "points", "LIMIT", N, "POINT", target[1], target[0])) - println(time.Since(start).String()) if err != nil { return err } diff --git a/tests/keys_test.go b/tests/keys_test.go index 9361e8c6..0b3217a6 100644 --- a/tests/keys_test.go +++ b/tests/keys_test.go @@ -32,6 +32,8 @@ func subTestKeys(t *testing.T, mc *mockServer) { runStep(t, mc, "WHEREEVAL", keys_WHEREEVAL_test) runStep(t, mc, "TYPE", keys_TYPE_test) runStep(t, mc, "FLUSHDB", keys_FLUSHDB_test) + runStep(t, mc, "HEALTHZ", keys_HEALTHZ_test) + } func keys_BOUNDS_test(mc *mockServer) error { @@ -540,3 +542,34 @@ func keys_FLUSHDB_test(mc *mockServer) error { Do("FLUSHDB").JSON().OK(), ) } + +func keys_HEALTHZ_test(mc *mockServer) error { + + // // follow and wait + // str, err := redis.String(mc.Do("FOLLOW", "localhost", mc.alt.port)) + // if err != nil { + // return err + // } + // if str != "OK" { + // return errors.New("not ok") + // } + // start := time.Now() + // for time.Since(start) < time.Second*5 { + // str, err = redis.String(mc.Do("HEALTHZ")) + // if str == "OK" { + // err = nil + // break + // } + // time.Sleep(time.Second / 4) + // } + // if err != nil { + // return err + // } + + return mc.DoBatch( + Do("HEALTHZ").OK(), + Do("HEALTHZ").JSON().OK(), + // Do("FOLLOW", "no", "one").OK(), + Do("HEALTHZ", "arg").Err(`wrong number of arguments for 'healthz' command`), + ) +} diff --git a/tests/mock_test.go b/tests/mock_test.go index a1aec6fb..cfd9c44d 100644 --- a/tests/mock_test.go +++ b/tests/mock_test.go @@ -38,9 +38,10 @@ type mockServer struct { port int conn redis.Conn ioJSON bool + // alt *mockServer } -func mockOpenServer(silent bool) (*mockServer, error) { +func mockOpenServer(silent, metrics bool) (*mockServer, error) { rand.Seed(time.Now().UnixNano()) port := rand.Int()%20000 + 20000 dir := fmt.Sprintf("data-mock-%d", port) @@ -56,11 +57,13 @@ func mockOpenServer(silent bool) (*mockServer, error) { tlog.SetOutput(logOutput) go func() { opts := server.Options{ - Host: "localhost", - Port: port, - Dir: dir, - UseHTTP: true, - MetricsAddr: ":4321", + Host: "localhost", + Port: port, + Dir: dir, + UseHTTP: true, + } + if metrics { + opts.MetricsAddr = ":4321" } if err := server.Serve(opts); err != nil { log.Fatal(err) diff --git a/tests/tests_test.go b/tests/tests_test.go index 5f20937d..be9d3b3a 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -38,11 +38,20 @@ func TestAll(t *testing.T) { os.Exit(1) }() - mc, err := mockOpenServer(false) + mc, err := mockOpenServer(false, true) if err != nil { t.Fatal(err) } defer mc.Close() + + // mc2, err := mockOpenServer(false, false) + // if err != nil { + // t.Fatal(err) + // } + // defer mc2.Close() + // mc.alt = mc2 + // mc2.alt = mc + runSubTest(t, "keys", mc, subTestKeys) runSubTest(t, "json", mc, subTestJSON) runSubTest(t, "search", mc, subTestSearch) @@ -71,10 +80,10 @@ func runStep(t *testing.T, mc *mockServer, name string, step func(mc *mockServer mc.ResetConn() defer mc.ResetConn() // clear the database so the test is consistent - if err := mc.DoBatch([][]interface{}{ - {"OUTPUT", "resp"}, {"OK"}, - {"FLUSHDB"}, {"OK"}, - }); err != nil { + if err := mc.DoBatch( + Do("OUTPUT", "resp").OK(), + Do("FLUSHDB").OK(), + ); err != nil { return err } if err := step(mc); err != nil { @@ -102,7 +111,7 @@ func BenchmarkAll(b *testing.B) { os.Exit(1) }() - mc, err := mockOpenServer(true) + mc, err := mockOpenServer(true, true) if err != nil { b.Fatal(err) }