github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/dgraph/cmd/alpha/mutations_mode/mutations_mode_test.go (about) 1 /* 2 * Copyright 2017-2018 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/dgraph-io/dgo" 25 "github.com/dgraph-io/dgo/protos/api" 26 "github.com/dgraph-io/dgraph/x" 27 "github.com/stretchr/testify/require" 28 29 "google.golang.org/grpc" 30 ) 31 32 // Tests in this file require a cluster running with the --mutations=<mode> option. 33 34 // Since this requires three alphas they will likely always be run with docker-compose, 35 // so no point in trying to use testutil.TestSockAddr here. 36 const disallowModeAlpha = "localhost:9180" 37 const strictModeAlphaGroup1 = "localhost:9182" 38 const strictModeAlphaGroup2 = "localhost:9183" 39 40 func runOn(conn *grpc.ClientConn, fn func(*testing.T, *dgo.Dgraph)) func(*testing.T) { 41 return func(t *testing.T) { 42 dg := dgo.NewDgraphClient(api.NewDgraphClient(conn)) 43 fn(t, dg) 44 } 45 } 46 47 func dropAllDisallowed(t *testing.T, dg *dgo.Dgraph) { 48 err := dg.Alter(context.Background(), &api.Operation{DropAll: true}) 49 50 require.Error(t, err) 51 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 52 } 53 54 func dropAllAllowed(t *testing.T, dg *dgo.Dgraph) { 55 err := dg.Alter(context.Background(), &api.Operation{DropAll: true}) 56 57 require.NoError(t, err) 58 } 59 60 func mutateNewDisallowed(t *testing.T, dg *dgo.Dgraph) { 61 ctx := context.Background() 62 63 txn := dg.NewTxn() 64 _, err := txn.Mutate(ctx, &api.Mutation{ 65 SetNquads: []byte(` 66 _:a <name> "Alice" . 67 `), 68 }) 69 70 require.Error(t, err) 71 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 72 } 73 74 func mutateNewDisallowed2(t *testing.T, dg *dgo.Dgraph) { 75 ctx := context.Background() 76 77 txn := dg.NewTxn() 78 _, err := txn.Mutate(ctx, &api.Mutation{ 79 SetNquads: []byte(` 80 _:a <name> "Alice" . 81 `), 82 }) 83 84 require.Error(t, err) 85 require.Contains(t, strings.ToLower(err.Error()), "schema not defined for predicate") 86 } 87 88 func addPredicateDisallowed(t *testing.T, dg *dgo.Dgraph) { 89 ctx := context.Background() 90 91 err := dg.Alter(ctx, &api.Operation{ 92 Schema: `name: string @index(exact) .`, 93 }) 94 95 require.Error(t, err) 96 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 97 } 98 99 func addPredicateAllowed1(t *testing.T, dg *dgo.Dgraph) { 100 ctx := context.Background() 101 102 err := dg.Alter(ctx, &api.Operation{ 103 Schema: `name: string @index(exact) .`, 104 }) 105 106 require.NoError(t, err) 107 } 108 109 func addPredicateAllowed2(t *testing.T, dg *dgo.Dgraph) { 110 ctx := context.Background() 111 112 err := dg.Alter(ctx, &api.Operation{ 113 Schema: `size: string @index(exact) .`, 114 }) 115 116 require.NoError(t, err) 117 } 118 119 func mutateExistingDisallowed(t *testing.T, dg *dgo.Dgraph) { 120 ctx := context.Background() 121 122 txn := dg.NewTxn() 123 _, err := txn.Mutate(ctx, &api.Mutation{ 124 SetNquads: []byte(` 125 _:a <dgraph.xid> "XID00001" . 126 `), 127 }) 128 129 require.NoError(t, txn.Discard(ctx)) 130 require.Error(t, err) 131 require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed") 132 } 133 134 func mutateExistingAllowed1(t *testing.T, dg *dgo.Dgraph) { 135 ctx := context.Background() 136 137 txn := dg.NewTxn() 138 _, err := txn.Mutate(ctx, &api.Mutation{ 139 SetNquads: []byte(` 140 _:a <name> "Alice" . 141 `), 142 }) 143 144 require.NoError(t, txn.Commit(ctx)) 145 require.NoError(t, err) 146 } 147 148 func mutateExistingAllowed2(t *testing.T, dg *dgo.Dgraph) { 149 ctx := context.Background() 150 151 txn := dg.NewTxn() 152 _, err := txn.Mutate(ctx, &api.Mutation{ 153 SetNquads: []byte(` 154 _:s <size> "small" . 155 `), 156 }) 157 158 require.NoError(t, txn.Commit(ctx)) 159 require.NoError(t, err) 160 } 161 162 func TestMutationsDisallow(t *testing.T) { 163 conn, err := grpc.Dial(disallowModeAlpha, grpc.WithInsecure()) 164 x.Check(err) 165 defer conn.Close() 166 167 t.Run("disallow drop all in no mutations mode", 168 runOn(conn, dropAllDisallowed)) 169 t.Run("disallow mutate new predicate in no mutations mode", 170 runOn(conn, mutateNewDisallowed)) 171 t.Run("disallow add predicate in no mutations mode", 172 runOn(conn, addPredicateDisallowed)) 173 t.Run("disallow mutate existing predicate in no mutations mode", 174 runOn(conn, mutateExistingDisallowed)) 175 } 176 177 func TestMutationsStrict(t *testing.T) { 178 conn1, err := grpc.Dial(strictModeAlphaGroup1, grpc.WithInsecure()) 179 x.Check(err) 180 defer conn1.Close() 181 182 conn2, err := grpc.Dial(strictModeAlphaGroup2, grpc.WithInsecure()) 183 x.Check(err) 184 defer conn2.Close() 185 186 t.Run("allow group1 drop all in strict mutations mode", 187 runOn(conn1, dropAllAllowed)) 188 t.Run("allow group2 drop all in strict mutations mode", 189 runOn(conn2, dropAllAllowed)) 190 t.Run("disallow group1 mutate new predicate in strict mutations mode", 191 runOn(conn1, mutateNewDisallowed2)) 192 t.Run("disallow group2 mutate new predicate in strict mutations mode", 193 runOn(conn2, mutateNewDisallowed2)) 194 t.Run("allow group1 add predicate in strict mutations mode", 195 runOn(conn1, addPredicateAllowed1)) 196 t.Run("allow group2 add predicate in strict mutations mode", 197 runOn(conn2, addPredicateAllowed2)) 198 t.Run("allow group1 mutate group1 predicate in strict mutations mode", 199 runOn(conn1, mutateExistingAllowed1)) 200 t.Run("allow group2 mutate group1 predicate in strict mutations mode", 201 runOn(conn2, mutateExistingAllowed1)) 202 t.Run("allow group1 mutate group2 predicate in strict mutations mode", 203 runOn(conn1, mutateExistingAllowed2)) 204 t.Run("allow group2 mutate group2 predicate in strict mutations mode", 205 runOn(conn2, mutateExistingAllowed2)) 206 }