From 367f68f4438e2b196365e155bfcc4be65afe1630 Mon Sep 17 00:00:00 2001 From: Seebs Date: Wed, 21 Sep 2022 17:08:56 -0500 Subject: [PATCH] restore commented-out test --- server/handler_test.go | 103 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/server/handler_test.go b/server/handler_test.go index bbda1599d..4f193f66e 100644 --- a/server/handler_test.go +++ b/server/handler_test.go @@ -13,17 +13,20 @@ import ( gohttp "net/http" "net/http/httptest" "reflect" + "sort" "strings" "sync" "testing" "time" - pilosa "github.com/featurebasedb/featurebase/v3" - "github.com/featurebasedb/featurebase/v3/boltdb" - "github.com/featurebasedb/featurebase/v3/encoding/proto" - "github.com/featurebasedb/featurebase/v3/pql" - "github.com/featurebasedb/featurebase/v3/server" - "github.com/featurebasedb/featurebase/v3/test" + pilosa "github.com/molecula/featurebase/v3" + "github.com/molecula/featurebase/v3/boltdb" + "github.com/molecula/featurebase/v3/encoding/proto" + "github.com/molecula/featurebase/v3/pql" + pb "github.com/molecula/featurebase/v3/proto" + "github.com/molecula/featurebase/v3/server" + "github.com/molecula/featurebase/v3/test" + "google.golang.org/grpc" ) func TestHandler_PostSchemaCluster(t *testing.T) { @@ -1405,6 +1408,94 @@ func TestClusterTranslator(t *testing.T) { } } +func TestQueryHistory(t *testing.T) { + cluster := test.MustRunCluster(t, 3, + []server.CommandOption{ + server.OptCommandServerOptions( + pilosa.OptServerNodeID("1"), + )}, + []server.CommandOption{ + server.OptCommandServerOptions( + pilosa.OptServerNodeID("0"), + )}, + []server.CommandOption{ + server.OptCommandServerOptions( + pilosa.OptServerNodeID("2"), + )}, + ) + defer cluster.Close() + + cmd := cluster.GetNode(0) + h := cmd.Handler.(*pilosa.Handler).Handler + + w := httptest.NewRecorder() + + test.Do(t, "POST", cmd.URL()+"/index/i0", "") + test.Do(t, "POST", cmd.URL()+"/index/i0/field/f0", "") + + gh := server.NewGRPCHandler(cmd.API) + stream := &MockServerTransportStream{} + ctx := grpc.NewContextWithServerTransportStream(context.Background(), stream) + _, err := gh.QuerySQLUnary(ctx, &pb.QuerySQLRequest{ + Sql: `select * from i0`, + }) + + if err != nil { + t.Fatalf("QuerySQLUnary failed: %v", err) + } + + test.Do(t, "POST", cmd.URL()+"/index/i0/query", "Set(0, f0=0)") + test.Do(t, "POST", cmd.URL()+"/index/i0/query", "Set(3000000, f0=0)") + test.Do(t, "POST", cmd.URL()+"/index/i0/query", "TopN(f0)") + + h.ServeHTTP(w, test.MustNewHTTPRequest("GET", "/query-history", nil)) + if w.Code != gohttp.StatusOK { + t.Fatalf("unexpected status code: %d %s", w.Code, w.Body.String()) + } + + ret := make([]pilosa.PastQueryStatus, 4) + b, err := ioutil.ReadAll(w.Body) + if err != nil { + t.Fatalf("reading: %v", err) + } + err = json.Unmarshal(b, &ret) + if err != nil { + t.Fatalf("unmarshalling: %v", err) + } + + // verify result length + if len(ret) != 4 { + // each set query executes on both nodes once + // topn query gets added to history on node0 once, node1 twice + t.Fatalf("expected list of length 4, got %d\n%+v", len(ret), ret) + } + + // verify sort order + if !sort.SliceIsSorted(ret, func(i, j int) bool { + // must match the sort in api.PastQueries + return ret[i].Start.After(ret[j].Start) + }) { + t.Fatalf("response list not sorted correctly") + } + + // verify some response values + if ret[0].Index != "i0" { + t.Fatalf("response value for 'Index' was '%s', expected 'i0'", ret[0].Index) + } + if ret[0].Node != cluster.GetNode(0).Server.NodeID() { + t.Fatalf("response value for 'Node' was '%s', expected '%s'", ret[0].Node, cluster.GetNode(0).Server.NodeID()) + } + if ret[3].PQL != "Extract(All(),Rows(f0))" { + t.Fatalf("response value for 'PQL' was '%s', expected 'Extract(All(),Rows(f0))'", ret[0].PQL) + } + if ret[3].SQL != "select * from i0" { + t.Fatalf("response value for 'SQL' was '%s', expected 'select * from i0'", ret[0].SQL) + } + if ret[0].PQL != "TopN(f0)" { + t.Fatalf("response value for 'PQL' was '%s', expected 'TopN(f0)'", ret[0].PQL) + } +} + func mustJSONDecode(t *testing.T, r io.Reader) (ret map[string]interface{}) { dec := json.NewDecoder(r) err := dec.Decode(&ret)