github.com/dshekhar95/sub_dgraph@v0.0.0-20230424164411-6be28e40bbf1/dgraph/cmd/alpha/mutations_mode/mutations_mode_test.go (about) 1 /* 2 * Copyright 2017-2022 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "context" 21 "strings" 22 "testing" 23 24 "github.com/stretchr/testify/require" 25 "google.golang.org/grpc" 26 "google.golang.org/grpc/credentials/insecure" 27 28 "github.com/dgraph-io/dgo/v210" 29 "github.com/dgraph-io/dgo/v210/protos/api" 30 "github.com/dgraph-io/dgraph/testutil" 31 ) 32 33 // Tests in this file require a cluster running with the --limit "mutations=<mode>;" flag. 34 35 func runOn(conn *grpc.ClientConn, fn func(*testing.T, *dgo.Dgraph)) func(*testing.T) { 36 return func(t *testing.T) { 37 dg := dgo.NewDgraphClient(api.NewDgraphClient(conn)) 38 fn(t, dg) 39 } 40 } 41 42 func dropAllDisallowed(t *testing.T, dg *dgo.Dgraph) { 43 err := dg.Alter(context.Background(), &api.Operation{DropAll: true}) 44 45 require.Error(t, err) 46 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 47 } 48 49 func dropAllAllowed(t *testing.T, dg *dgo.Dgraph) { 50 err := dg.Alter(context.Background(), &api.Operation{DropAll: true}) 51 52 require.NoError(t, err) 53 } 54 55 func mutateNewDisallowed(t *testing.T, dg *dgo.Dgraph) { 56 ctx := context.Background() 57 58 txn := dg.NewTxn() 59 _, err := txn.Mutate(ctx, &api.Mutation{ 60 SetNquads: []byte(` 61 _:a <name> "Alice" . 62 `), 63 }) 64 65 require.Error(t, err) 66 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 67 } 68 69 func mutateNewDisallowed2(t *testing.T, dg *dgo.Dgraph) { 70 ctx := context.Background() 71 72 txn := dg.NewTxn() 73 _, err := txn.Mutate(ctx, &api.Mutation{ 74 SetNquads: []byte(` 75 _:a <name> "Alice" . 76 `), 77 }) 78 79 require.Error(t, err) 80 require.Contains(t, strings.ToLower(err.Error()), "schema not defined for predicate") 81 } 82 83 func addPredicateDisallowed(t *testing.T, dg *dgo.Dgraph) { 84 ctx := context.Background() 85 86 err := dg.Alter(ctx, &api.Operation{ 87 Schema: `name: string @index(exact) .`, 88 }) 89 90 require.Error(t, err) 91 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 92 } 93 94 func addPredicateAllowed1(t *testing.T, dg *dgo.Dgraph) { 95 ctx := context.Background() 96 97 err := dg.Alter(ctx, &api.Operation{ 98 Schema: `name: string @index(exact) .`, 99 }) 100 101 require.NoError(t, err) 102 } 103 104 func addPredicateAllowed2(t *testing.T, dg *dgo.Dgraph) { 105 ctx := context.Background() 106 107 err := dg.Alter(ctx, &api.Operation{ 108 Schema: `size: string @index(exact) .`, 109 }) 110 111 require.NoError(t, err) 112 } 113 114 func mutateExistingDisallowed(t *testing.T, dg *dgo.Dgraph) { 115 ctx := context.Background() 116 117 txn := dg.NewTxn() 118 _, err := txn.Mutate(ctx, &api.Mutation{ 119 SetNquads: []byte(` 120 _:a <dgraph.xid> "XID00001" . 121 `), 122 }) 123 124 require.NoError(t, txn.Discard(ctx)) 125 require.Error(t, err) 126 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 127 } 128 129 func mutateExistingAllowed1(t *testing.T, dg *dgo.Dgraph) { 130 ctx := context.Background() 131 132 txn := dg.NewTxn() 133 _, err := txn.Mutate(ctx, &api.Mutation{ 134 SetNquads: []byte(` 135 _:a <name> "Alice" . 136 `), 137 }) 138 139 require.NoError(t, txn.Commit(ctx)) 140 require.NoError(t, err) 141 } 142 143 func mutateExistingAllowed2(t *testing.T, dg *dgo.Dgraph) { 144 ctx := context.Background() 145 146 txn := dg.NewTxn() 147 _, err := txn.Mutate(ctx, &api.Mutation{ 148 SetNquads: []byte(` 149 _:s <size> "small" . 150 `), 151 }) 152 153 require.NoError(t, txn.Commit(ctx)) 154 require.NoError(t, err) 155 } 156 157 func TestMutationsDisallow(t *testing.T) { 158 a := testutil.ContainerAddr("alpha1", 9080) 159 conn, err := grpc.Dial(a, grpc.WithTransportCredentials(insecure.NewCredentials())) 160 if err != nil { 161 t.Fatalf("Cannot perform drop all op: %s", err.Error()) 162 } 163 defer conn.Close() 164 165 t.Run("disallow drop all in no mutations mode", 166 runOn(conn, dropAllDisallowed)) 167 t.Run("disallow mutate new predicate in no mutations mode", 168 runOn(conn, mutateNewDisallowed)) 169 t.Run("disallow add predicate in no mutations mode", 170 runOn(conn, addPredicateDisallowed)) 171 t.Run("disallow mutate existing predicate in no mutations mode", 172 runOn(conn, mutateExistingDisallowed)) 173 } 174 175 func TestMutationsStrict(t *testing.T) { 176 a1 := testutil.ContainerAddr("alpha2", 9080) 177 conn1, err := grpc.Dial(a1, grpc.WithTransportCredentials(insecure.NewCredentials())) 178 if err != nil { 179 t.Fatalf("Cannot perform drop all op: %s", err.Error()) 180 } 181 defer conn1.Close() 182 183 a2 := testutil.ContainerAddr("alpha3", 9080) 184 conn2, err := grpc.Dial(a2, grpc.WithTransportCredentials(insecure.NewCredentials())) 185 if err != nil { 186 t.Fatalf("Cannot perform drop all op: %s", err.Error()) 187 } 188 defer conn2.Close() 189 190 t.Run("allow group1 drop all in strict mutations mode", 191 runOn(conn1, dropAllAllowed)) 192 t.Run("allow group2 drop all in strict mutations mode", 193 runOn(conn2, dropAllAllowed)) 194 t.Run("disallow group1 mutate new predicate in strict mutations mode", 195 runOn(conn1, mutateNewDisallowed2)) 196 t.Run("disallow group2 mutate new predicate in strict mutations mode", 197 runOn(conn2, mutateNewDisallowed2)) 198 t.Run("allow group1 add predicate in strict mutations mode", 199 runOn(conn1, addPredicateAllowed1)) 200 t.Run("allow group2 add predicate in strict mutations mode", 201 runOn(conn2, addPredicateAllowed2)) 202 t.Run("allow group1 mutate group1 predicate in strict mutations mode", 203 runOn(conn1, mutateExistingAllowed1)) 204 t.Run("allow group2 mutate group1 predicate in strict mutations mode", 205 runOn(conn2, mutateExistingAllowed1)) 206 t.Run("allow group1 mutate group2 predicate in strict mutations mode", 207 runOn(conn1, mutateExistingAllowed2)) 208 t.Run("allow group2 mutate group2 predicate in strict mutations mode", 209 runOn(conn2, mutateExistingAllowed2)) 210 }