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  }