From 884dab65d245e5b3cc8f3d2887b0be7514be20dd Mon Sep 17 00:00:00 2001 From: shivaji-dgraph Date: Mon, 6 Jan 2025 15:38:39 +0530 Subject: [PATCH] refactor test code --- chunker/json_parser_test.go | 36 +++++-- contrib/integration/testtxn/main_test.go | 80 +++++++-------- dgraph/cmd/alpha/http_test.go | 16 +-- dgraph/cmd/alpha/run_test.go | 94 +++++++++++------- dgraph/cmd/alpha/upsert_test.go | 5 +- dgraphapi/schema.go | 118 +++++++++++++++++++++++ dgraphtest/local_cluster.go | 4 + 7 files changed, 259 insertions(+), 94 deletions(-) create mode 100644 dgraphapi/schema.go diff --git a/chunker/json_parser_test.go b/chunker/json_parser_test.go index 6752b8c150a..29719434eba 100644 --- a/chunker/json_parser_test.go +++ b/chunker/json_parser_test.go @@ -25,6 +25,7 @@ import ( "encoding/json" "fmt" "math" + "os" "testing" "time" @@ -32,9 +33,16 @@ import ( "github.com/stretchr/testify/require" "github.com/dgraph-io/dgo/v240/protos/api" + "github.com/dgraph-io/dgraph/v24/dgraphapi" + "github.com/dgraph-io/dgraph/v24/dgraphtest" "github.com/dgraph-io/dgraph/v24/testutil" "github.com/dgraph-io/dgraph/v24/tok" "github.com/dgraph-io/dgraph/v24/types" + "github.com/dgraph-io/dgraph/v24/x" +) + +var ( + dg *dgraphapi.GrpcClient ) func makeNquad(sub, pred string, val *api.Value) *api.NQuad { @@ -96,17 +104,12 @@ func FastParse(b []byte, op int) ([]*api.NQuad, error) { func (exp *Experiment) verify() { // insert the data into dgraph - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - if err != nil { - exp.t.Fatalf("Error while getting a dgraph client: %v", err) - } - ctx := context.Background() + require.NoError(exp.t, dg.Login(ctx, dgraphapi.DefaultUser, dgraphapi.DefaultPassword)) require.NoError(exp.t, dg.Alter(ctx, &api.Operation{DropAll: true}), "drop all failed") require.NoError(exp.t, dg.Alter(ctx, &api.Operation{Schema: exp.schema}), "schema change failed") - - _, err = dg.NewTxn().Mutate(ctx, + _, err := dg.NewTxn().Mutate(ctx, &api.Mutation{Set: exp.nqs, CommitNow: true}) require.NoError(exp.t, err, "mutation failed") @@ -1512,3 +1515,22 @@ func TestNquadsJsonValidVector(t *testing.T) { exp.nqs = fastNQ exp.verify() } + +func TestMain(m *testing.M) { + conf := dgraphtest.NewClusterConfig().WithNumAlphas(1).WithNumZeros(1).WithReplicas(1).WithACL(time.Hour) + c, err := dgraphtest.NewLocalCluster(conf) + + x.Panic(err) + x.Panic(c.Start()) + var cleanup func() + dg, cleanup, err = c.Client() + x.Panic(err) + defer cleanup() + code := m.Run() + if code != 0 { + c.Cleanup(true) + } else { + c.Cleanup(false) + } + os.Exit(code) +} diff --git a/contrib/integration/testtxn/main_test.go b/contrib/integration/testtxn/main_test.go index 4f6cfba29da..5928f09eef5 100644 --- a/contrib/integration/testtxn/main_test.go +++ b/contrib/integration/testtxn/main_test.go @@ -35,21 +35,30 @@ import ( "github.com/dgraph-io/dgo/v240" "github.com/dgraph-io/dgo/v240/protos/api" - "github.com/dgraph-io/dgraph/v24/testutil" + "github.com/dgraph-io/dgraph/v24/dgraphapi" + "github.com/dgraph-io/dgraph/v24/dgraphtest" "github.com/dgraph-io/dgraph/v24/x" ) type state struct { - dg *dgo.Dgraph + dg *dgraphapi.GrpcClient } var s state func TestMain(m *testing.M) { log.SetFlags(log.LstdFlags | log.Lshortfile) - x.Panic(testutil.AssignUids(200)) - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) + conf := dgraphtest.NewClusterConfig().WithNumAlphas(1).WithNumZeros(1).WithReplicas(1).WithACL(time.Hour) + c, err := dgraphtest.NewLocalCluster(conf) + + x.Panic(err) + x.Panic(c.Start()) + dg, cleanup, err := c.Client() x.Panic(err) + defer cleanup() + + x.Panic(dg.Login(context.Background(), dgraphapi.DefaultUser, dgraphapi.DefaultPassword)) + x.Panic(c.AssignUids(dg.Dgraph, 200)) s.dg = dg _ = m.Run() } @@ -724,25 +733,23 @@ query countAnswers($num: int) { ) func TestCountIndexConcurrentTxns(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - testutil.DropAll(t, dg) - alterSchema(t, dg, "answer: [uid] @count .") + require.NoError(t, s.dg.DropAll()) + require.NoError(t, s.dg.SetupSchema("answer: [uid] @count .")) // Expected edge count of 0x100: 1 - txn0 := dg.NewTxn() + txn0 := s.dg.NewTxn() mu := api.Mutation{SetNquads: []byte("<0x100> <0x200> .")} - _, err = txn0.Mutate(ctxb, &mu) + _, err := txn0.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn0.Commit(ctxb)) // The following two mutations are in separate interleaved txns. - txn1 := dg.NewTxn() + txn1 := s.dg.NewTxn() mu = api.Mutation{SetNquads: []byte("<0x1> <0x2> .")} _, err = txn1.Mutate(ctxb, &mu) require.NoError(t, err) - txn2 := dg.NewTxn() + txn2 := s.dg.NewTxn() mu = api.Mutation{SetNquads: []byte("<0x1> <0x3> .")} _, err = txn2.Mutate(ctxb, &mu) require.NoError(t, err) @@ -752,13 +759,13 @@ func TestCountIndexConcurrentTxns(t *testing.T) { "the txn2 should be aborted due to concurrent update on the count index of <0x01>") // retry the mutation - txn3 := dg.NewTxn() + txn3 := s.dg.NewTxn() _, err = txn3.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn3.Commit(ctxb)) // Verify count queries - txn := dg.NewReadOnlyTxn() + txn := s.dg.NewReadOnlyTxn() vars := map[string]string{"$num": "1"} resp, err := txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -766,7 +773,7 @@ func TestCountIndexConcurrentTxns(t *testing.T) { require.JSONEq(t, `{"me": [{"count(answer)": 1, "uid": "0x100"}]}`, js) - txn = dg.NewReadOnlyTxn() + txn = s.dg.NewReadOnlyTxn() vars = map[string]string{"$num": "2"} resp, err = txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -777,35 +784,33 @@ func TestCountIndexConcurrentTxns(t *testing.T) { } func TestCountIndexSerialTxns(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - testutil.DropAll(t, dg) - alterSchema(t, dg, "answer: [uid] @count .") + require.NoError(t, s.dg.DropAll()) + require.NoError(t, s.dg.SetupSchema("answer: [uid] @count .")) // Expected Edge count of 0x100: 1 - txn0 := dg.NewTxn() + txn0 := s.dg.NewTxn() mu := api.Mutation{SetNquads: []byte("<0x100> <0x200> .")} - _, err = txn0.Mutate(ctxb, &mu) + _, err := txn0.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn0.Commit(ctxb)) // Expected edge count of 0x1: 2 // This should NOT appear in the query result // The following two mutations are in serial txns. - txn1 := dg.NewTxn() + txn1 := s.dg.NewTxn() mu = api.Mutation{SetNquads: []byte("<0x1> <0x2> .")} _, err = txn1.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn1.Commit(ctxb)) - txn2 := dg.NewTxn() + txn2 := s.dg.NewTxn() mu = api.Mutation{SetNquads: []byte("<0x1> <0x3> .")} _, err = txn2.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn2.Commit(ctxb)) // Verify query - txn := dg.NewReadOnlyTxn() + txn := s.dg.NewReadOnlyTxn() vars := map[string]string{"$num": "1"} resp, err := txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -813,7 +818,7 @@ func TestCountIndexSerialTxns(t *testing.T) { require.JSONEq(t, `{"me": [{"count(answer)": 1, "uid": "0x100"}]}`, js) - txn = dg.NewReadOnlyTxn() + txn = s.dg.NewReadOnlyTxn() vars = map[string]string{"$num": "2"} resp, err = txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -824,22 +829,20 @@ func TestCountIndexSerialTxns(t *testing.T) { } func TestCountIndexSameTxn(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - testutil.DropAll(t, dg) - alterSchema(t, dg, "answer: [uid] @count .") + require.NoError(t, s.dg.DropAll()) + require.NoError(t, s.dg.SetupSchema("answer: [uid] @count .")) // Expected Edge count of 0x100: 1 - txn0 := dg.NewTxn() + txn0 := s.dg.NewTxn() mu := api.Mutation{SetNquads: []byte("<0x100> <0x200> .")} - _, err = txn0.Mutate(ctxb, &mu) + _, err := txn0.Mutate(ctxb, &mu) require.NoError(t, err) require.NoError(t, txn0.Commit(ctxb)) // Expected edge count of 0x1: 2 // This should NOT appear in the query result // The following two mutations are in the same txn. - txn1 := dg.NewTxn() + txn1 := s.dg.NewTxn() mu = api.Mutation{SetNquads: []byte("<0x1> <0x2> .")} _, err = txn1.Mutate(ctxb, &mu) require.NoError(t, err) @@ -849,7 +852,7 @@ func TestCountIndexSameTxn(t *testing.T) { require.NoError(t, txn1.Commit(ctxb)) // Verify query - txn := dg.NewReadOnlyTxn() + txn := s.dg.NewReadOnlyTxn() vars := map[string]string{"$num": "1"} resp, err := txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -857,7 +860,7 @@ func TestCountIndexSameTxn(t *testing.T) { require.JSONEq(t, `{"me": [{"count(answer)": 1, "uid": "0x100"}]}`, js) - txn = dg.NewReadOnlyTxn() + txn = s.dg.NewReadOnlyTxn() vars = map[string]string{"$num": "2"} resp, err = txn.QueryWithVars(ctxb, countQuery, vars) require.NoError(t, err) @@ -868,9 +871,8 @@ func TestCountIndexSameTxn(t *testing.T) { } func TestConcurrentQueryMutate(t *testing.T) { - testutil.DropAll(t, s.dg) - alterSchema(t, s.dg, "name: string .") - + require.NoError(t, s.dg.DropAll()) + require.NoError(t, s.dg.SetupSchema("name: string .")) txn := s.dg.NewTxn() defer func() { require.NoError(t, txn.Discard(context.Background())) }() @@ -904,8 +906,8 @@ func TestConcurrentQueryMutate(t *testing.T) { } func TestTxnDiscardBeforeCommit(t *testing.T) { - testutil.DropAll(t, s.dg) - alterSchema(t, s.dg, "name: string .") + require.NoError(t, s.dg.DropAll()) + require.NoError(t, s.dg.SetupSchema("name: string .")) txn := s.dg.NewTxn() mu := &api.Mutation{ diff --git a/dgraph/cmd/alpha/http_test.go b/dgraph/cmd/alpha/http_test.go index 3173eea4374..f91dec8a6ad 100644 --- a/dgraph/cmd/alpha/http_test.go +++ b/dgraph/cmd/alpha/http_test.go @@ -35,9 +35,9 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + "github.com/dgraph-io/dgraph/v24/dgraphapi" "github.com/dgraph-io/dgraph/v24/protos/pb" "github.com/dgraph-io/dgraph/v24/query" - "github.com/dgraph-io/dgraph/v24/testutil" "github.com/dgraph-io/dgraph/v24/x" ) @@ -846,13 +846,13 @@ func setDrainingMode(t *testing.T, enable bool, accessJwt string) { } } }` - params := &testutil.GraphQLParams{ + params := dgraphapi.GraphQLParams{ Query: drainingRequest, Variables: map[string]interface{}{"enable": enable}, } - resp := testutil.MakeGQLRequestWithAccessJwt(t, params, accessJwt) - resp.RequireNoGraphQLErrors(t) - require.JSONEq(t, `{"draining":{"response":{"code":"Success"}}}`, string(resp.Data)) + resp, err := hc.RunGraphqlQuery(params, true) + require.NoError(t, err) + require.JSONEq(t, `{"draining":{"response":{"code":"Success"}}}`, string(resp)) } func TestDrainingMode(t *testing.T) { @@ -894,12 +894,12 @@ func TestDrainingMode(t *testing.T) { } - token := testutil.GrootHttpLogin(addr + "/admin") + require.NoError(t, hc.LoginIntoNamespace(dgraphapi.DefaultUser, dgraphapi.DefaultPassword, 0)) - setDrainingMode(t, true, token.AccessJwt) + setDrainingMode(t, true, hc.AccessJwt) runRequests(true) - setDrainingMode(t, false, token.AccessJwt) + setDrainingMode(t, false, hc.AccessJwt) runRequests(false) } diff --git a/dgraph/cmd/alpha/run_test.go b/dgraph/cmd/alpha/run_test.go index 87188b62842..011ca0e28d5 100644 --- a/dgraph/cmd/alpha/run_test.go +++ b/dgraph/cmd/alpha/run_test.go @@ -46,11 +46,12 @@ import ( "github.com/dgraph-io/dgo/v240" "github.com/dgraph-io/dgo/v240/protos/api" + "github.com/dgraph-io/dgraph/v24/dgraphapi" + "github.com/dgraph-io/dgraph/v24/dgraphtest" "github.com/dgraph-io/dgraph/v24/dql" "github.com/dgraph-io/dgraph/v24/protos/pb" "github.com/dgraph-io/dgraph/v24/query" "github.com/dgraph-io/dgraph/v24/schema" - "github.com/dgraph-io/dgraph/v24/testutil" "github.com/dgraph-io/dgraph/v24/x" ) @@ -64,7 +65,16 @@ func defaultContext() context.Context { return context.WithValue(context.Background(), mutationAllowedKey, true) } -var ts uint64 +var ( + addr string + alphaSockAdd string + dg *dgraphapi.GrpcClient + hc *dgraphapi.HTTPClient + ts uint64 + // the grootAccessJWT stores the access JWT extracted from the response + // of http login + token *Token +) func timestamp() uint64 { return atomic.AddUint64(&ts, 1) @@ -245,7 +255,7 @@ func TestDeletePredicate(t *testing.T) { output, err = runGraphqlQuery(`schema{}`) require.NoError(t, err) - testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse(testutil.SchemaOptions{ + dgraphapi.CompareJSON(dgraphapi.GetFullSchemaHTTPResponse(dgraphapi.SchemaOptions{ UserPreds: `{"predicate":"age","type":"default"},` + `{"predicate":"name","type":"string","index":true, "tokenizer":["term"]}`}), output) @@ -1027,8 +1037,8 @@ func TestListTypeSchemaChange(t *testing.T) { q = `schema{}` res, err = runGraphqlQuery(q) require.NoError(t, err) - testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse( - testutil.SchemaOptions{UserPreds: `{"predicate":"occupations","type":"string"}`}), res) + dgraphapi.CompareJSON(dgraphapi.GetFullSchemaHTTPResponse( + dgraphapi.SchemaOptions{UserPreds: `{"predicate":"occupations","type":"string"}`}), res) } func TestDeleteAllSP2(t *testing.T) { @@ -1262,7 +1272,7 @@ func TestDropAll(t *testing.T) { q3 := "schema{}" output, err = runGraphqlQuery(q3) require.NoError(t, err) - testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse(testutil.SchemaOptions{}), output) + dgraphapi.CompareJSON(dgraphapi.GetFullSchemaHTTPResponse(dgraphapi.SchemaOptions{}), output) // Reinstate schema so that we can re-run the original query. require.NoError(t, alterSchemaWithRetry(s)) @@ -1313,7 +1323,7 @@ func TestJsonUnicode(t *testing.T) { } func TestGrpcCompressionSupport(t *testing.T) { - conn, err := grpc.Dial(testutil.SockAddr, + conn, err := grpc.NewClient(alphaSockAdd, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)), ) @@ -1511,9 +1521,6 @@ func TestJSONQueryWithVariables(t *testing.T) { } func TestGeoDataInvalidString(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - ctx := context.Background() require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) require.NoError(t, dg.Alter(ctx, &api.Operation{Schema: `loc: geo .`})) @@ -1527,7 +1534,7 @@ func TestGeoDataInvalidString(t *testing.T) { }, }, } - _, err = dg.NewTxn().Mutate(ctx, &api.Mutation{ + _, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, Set: []*api.NQuad{n}, }) @@ -1538,9 +1545,6 @@ func TestGeoDataInvalidString(t *testing.T) { // succeeds querying the data returns an error. Ideally, we should not accept // invalid data in a mutation though that is left as future work. func TestGeoCorruptData(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - ctx := context.Background() require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) require.NoError(t, dg.Alter(ctx, &api.Operation{Schema: `loc: geo .`})) @@ -1554,7 +1558,7 @@ func TestGeoCorruptData(t *testing.T) { }, }, } - _, err = dg.NewTxn().Mutate(ctx, &api.Mutation{ + _, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, Set: []*api.NQuad{n}, }) @@ -1575,9 +1579,6 @@ func TestGeoCorruptData(t *testing.T) { // As far as I (Aman) know, this is something that should not be used // by a common user unless user knows what she is doing. func TestGeoValidWkbData(t *testing.T) { - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err) - ctx := context.Background() require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) require.NoError(t, dg.Alter(ctx, &api.Operation{Schema: `loc: geo .`})) @@ -1615,17 +1616,11 @@ func TestGeoValidWkbData(t *testing.T) { require.Contains(t, string(resp.Json), `{"type":"Point","coordinates":[1,2]}`) } -var addr string - type Token struct { - token *testutil.HttpToken + token *dgraphapi.HttpToken sync.RWMutex } -// // the grootAccessJWT stores the access JWT extracted from the response -// // of http login -var token *Token - func (t *Token) getAccessJWTToken() string { t.RLock() defer t.RUnlock() @@ -1635,22 +1630,39 @@ func (t *Token) getAccessJWTToken() string { func (t *Token) refreshToken() error { t.Lock() defer t.Unlock() - newToken, err := testutil.HttpLogin(&testutil.LoginParams{ - Endpoint: addr + "/admin", - RefreshJwt: t.token.RefreshToken, - }) + err := hc.LoginUsingToken(0) if err != nil { return err } - t.token.AccessJwt = newToken.AccessJwt - t.token.RefreshToken = newToken.RefreshToken + t.token.AccessJwt = hc.AccessJwt + t.token.RefreshToken = hc.RefreshToken return nil } func TestMain(m *testing.M) { - addr = "http://" + testutil.SockAddrHttp + conf := dgraphtest.NewClusterConfig().WithNumAlphas(1).WithNumZeros(1).WithReplicas(1).WithACL(time.Hour) + c, err := dgraphtest.NewLocalCluster(conf) + + x.Panic(err) + x.Panic(c.Start()) + var cleanup func() + dg, cleanup, err = c.Client() + x.Panic(err) + defer cleanup() + + x.Panic(dg.Login(context.Background(), dgraphapi.DefaultUser, dgraphapi.DefaultPassword)) + + alphaSockAdd, err = c.GetAlphaGrpcPublicPort() + x.Panic(err) + + alphaSockAddHttp, err := c.GetAlphaHttpPublicPort() + x.Panic(err) + addr = "http://0.0.0.0:" + alphaSockAddHttp + zeroSockAdd, err := c.GetZeroGrpcPublicPort() + x.Panic(err) + // Increment lease, so that mutations work. - conn, err := grpc.Dial(testutil.SockAddrZero, grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.NewClient("0.0.0.0:"+zeroSockAdd, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatal(err) } @@ -1659,11 +1671,21 @@ func TestMain(m *testing.M) { &pb.Num{Val: 1e6, Type: pb.Num_UID}); err != nil { log.Fatal(err) } - httpToken := testutil.GrootHttpLogin(addr + "/admin") + hc, err = c.HTTPClient() + x.Panic(err) + + x.Panic(hc.LoginIntoNamespace(dgraphapi.DefaultUser, dgraphapi.DefaultPassword, 0)) + + httpToken := hc.HttpToken token = &Token{ token: httpToken, RWMutex: sync.RWMutex{}, } - r := m.Run() - os.Exit(r) + code := m.Run() + if code != 0 { + c.Cleanup(true) + } else { + c.Cleanup(false) + } + os.Exit(code) } diff --git a/dgraph/cmd/alpha/upsert_test.go b/dgraph/cmd/alpha/upsert_test.go index 5f596ef4a23..223e8f16682 100644 --- a/dgraph/cmd/alpha/upsert_test.go +++ b/dgraph/cmd/alpha/upsert_test.go @@ -2221,9 +2221,6 @@ upsert { func TestEmptyRequest(t *testing.T) { // We are using the dgo client in this test here to test the grpc interface - dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr) - require.NoError(t, err, "error while getting a dgraph client") - require.NoError(t, dg.Alter(context.Background(), &api.Operation{ DropOp: api.Operation_ALL, })) @@ -2234,7 +2231,7 @@ branch: string . amount: float .`})) req := &api.Request{} - _, err = dg.NewTxn().Do(context.Background(), req) + _, err := dg.NewTxn().Do(context.Background(), req) require.Contains(t, strings.ToLower(err.Error()), "empty request") } diff --git a/dgraphapi/schema.go b/dgraphapi/schema.go new file mode 100644 index 00000000000..57691b7bd04 --- /dev/null +++ b/dgraphapi/schema.go @@ -0,0 +1,118 @@ +/* + * Copyright 2025 Dgraph Labs, Inc. and Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dgraphapi + +import "fmt" + +const ( + aclPreds = ` +{"predicate":"dgraph.xid","type":"string", "index":true, "tokenizer":["exact"], "unique": true, "upsert":true}, +{"predicate":"dgraph.password","type":"password"}, +{"predicate":"dgraph.user.group","list":true, "reverse":true, "type":"uid"}, +{"predicate":"dgraph.acl.rule","type":"uid","list":true}, +{"predicate":"dgraph.rule.predicate","type":"string","index":true,"tokenizer":["exact"],"upsert":true}, +{"predicate":"dgraph.rule.permission","type":"int"} +` + otherInternalPreds = ` +{"predicate":"dgraph.type","type":"string","index":true,"tokenizer":["exact"],"list":true}, +{"predicate":"dgraph.drop.op", "type": "string"}, +{"predicate":"dgraph.graphql.p_query","type":"string","index":true,"tokenizer":["sha256"]}, +{"predicate":"dgraph.graphql.schema", "type": "string"}, +{"predicate":"dgraph.graphql.xid","type":"string","index":true,"tokenizer":["exact"],"upsert":true} +` + aclTypes = ` +{ + "fields": [{"name": "dgraph.password"},{"name": "dgraph.xid"},{"name": "dgraph.user.group"}], + "name": "dgraph.type.User" +},{ + "fields": [{"name": "dgraph.acl.rule"},{"name": "dgraph.xid"}], + "name": "dgraph.type.Group" +},{ + "fields": [{"name": "dgraph.rule.predicate"},{"name": "dgraph.rule.permission"}], + "name": "dgraph.type.Rule" +} +` + otherInternalTypes = ` +{ + "fields": [{"name": "dgraph.graphql.schema"},{"name": "dgraph.graphql.xid"}], + "name": "dgraph.graphql" +},{ + "fields": [{"name": "dgraph.graphql.p_query"}], + "name": "dgraph.graphql.persisted_query" +} +` +) + +type SchemaOptions struct { + UserPreds string + UserTypes string + ExcludeAclSchema bool +} + +// GetFullSchemaHTTPResponse returns a string representation of the HTTP response returned by the +// full schema{} query. It uses the user provided predicates and types along with the initial +// internal schema to generate the string. Example response looks like: +// +// { +// "data": { +// "schema": [ ... ], +// "types": [ ... ] +// } +// } +func GetFullSchemaHTTPResponse(opts SchemaOptions) string { + return `{"data":` + GetFullSchemaJSON(opts) + `}` +} + +// GetFullSchemaJSON returns a string representation of the JSON object returned by the full +// schema{} query. It uses the user provided predicates and types along with the initial internal +// schema to generate the string. Example response looks like: +// +// { +// "schema": [ ... ], +// "types": [ ... ] +// } +func GetFullSchemaJSON(opts SchemaOptions) string { + expectedPreds := GetInternalPreds(opts.ExcludeAclSchema) + if len(opts.UserPreds) > 0 { + expectedPreds += "," + opts.UserPreds + } + + expectedTypes := GetInternalTypes(opts.ExcludeAclSchema) + if len(opts.UserTypes) > 0 { + expectedTypes += "," + opts.UserTypes + } + + return fmt.Sprintf(` + { + "schema": [%s], + "types": [%s] + }`, expectedPreds, expectedTypes) +} + +func GetInternalPreds(excludeAclPreds bool) string { + if excludeAclPreds { + return otherInternalPreds + } + return aclPreds + "," + otherInternalPreds +} + +func GetInternalTypes(excludeAclTypes bool) string { + if excludeAclTypes { + return otherInternalTypes + } + return aclTypes + "," + otherInternalTypes +} diff --git a/dgraphtest/local_cluster.go b/dgraphtest/local_cluster.go index d12ddad3346..4a0af0132cb 100644 --- a/dgraphtest/local_cluster.go +++ b/dgraphtest/local_cluster.go @@ -1177,6 +1177,10 @@ func (c *LocalCluster) GetAlphaHttpPublicPort() (string, error) { return publicPort(c.dcli, c.alphas[0], alphaHttpPort) } +func (c *LocalCluster) GetZeroGrpcPublicPort() (string, error) { + return publicPort(c.dcli, c.zeros[0], zeroGrpcPort) +} + func (c *LocalCluster) GetTempDir() string { return c.tempBinDir }