Skip to content

Commit

Permalink
Issue 2277: Add strict schema mode (#2863)
Browse files Browse the repository at this point in the history
Fixes #2277.

* Add --mutations option.

* Check strict mode and schema before allowing mutation.

* Remove --nomutations option.

* Add tests of strict schema with multi-group cluster.

* Refactor out code duplicated in proposeOrSend() and Mutate().

* Log message when server is ready to accept requests.

* Check for error instead of predicate type to detect undefined predicates.

* Replace nomutations test with mutations_mode test.
  • Loading branch information
codexnull authored Jan 10, 2019
1 parent dfbeec1 commit 976b498
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 172 deletions.
104 changes: 104 additions & 0 deletions dgraph/cmd/alpha/mutations_mode/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# This file sets up the cluster required by the tests in this directory.
version: "3.5"
services:
zero1:
image: dgraph/dgraph:latest
container_name: bank-dg0.1
working_dir: /data/dg0.1
ports:
- 5080:5080
- 6080:6080
labels:
cluster: test
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
command: /gobin/dgraph zero -o 0 --my=zero1:5080 --replicas 1 --idx 1 --logtostderr

zero2:
image: dgraph/dgraph:latest
container_name: bank-dg0.2
depends_on:
- zero1
ports:
- 5082:5082
- 6082:6082
labels:
cluster: test
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
command: /gobin/dgraph zero -o 2 --my=zero2:5082 --replicas 1 --idx 2 --logtostderr --peer=zero1:5080

zero3:
image: dgraph/dgraph:latest
container_name: bank-dg0.3
depends_on:
- zero2
ports:
- 5083:5083
- 6083:6083
labels:
cluster: test
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
command: /gobin/dgraph zero -o 3 --my=zero3:5083 --replicas 1 --idx 3 --logtostderr --peer=zero1:5080

dg1:
image: dgraph/dgraph:latest
container_name: bank-dg1
working_dir: /data/dg1
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
ports:
- 8180:8180
- 9180:9180
labels:
cluster: test
command: /gobin/dgraph alpha --my=dg1:7180 --lru_mb=1024 --zero=zero1:5080 -o 100 --logtostderr --mutations=disallow

dg2:
image: dgraph/dgraph:latest
container_name: bank-dg2
working_dir: /data/dg2
depends_on:
- dg1
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
ports:
- 8182:8182
- 9182:9182
labels:
cluster: test
command: /gobin/dgraph alpha --my=dg2:7182 --lru_mb=1024 --zero=zero1:5080 -o 102 --logtostderr --mutations=strict

dg3:
image: dgraph/dgraph:latest
container_name: bank-dg3
working_dir: /data/dg3
depends_on:
- dg2
volumes:
- type: bind
source: $GOPATH/bin
target: /gobin
read_only: true
ports:
- 8183:8183
- 9183:9183
labels:
cluster: test
command: /gobin/dgraph alpha --my=dg3:7183 --lru_mb=1024 --zero=zero1:5080 -o 103 --logtostderr --mutations=strict
204 changes: 204 additions & 0 deletions dgraph/cmd/alpha/mutations_mode/mutations_mode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
* Copyright 2017-2018 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 main

import (
"context"
"strings"
"testing"

"github.com/dgraph-io/dgo"
"github.com/dgraph-io/dgo/protos/api"
"github.com/dgraph-io/dgraph/x"
"github.com/stretchr/testify/require"

"google.golang.org/grpc"
)

// Tests in this file require a cluster running with the --mutations=<mode> option.

const disallowModeAlpha = "localhost:9180"
const strictModeAlphaGroup1 = "localhost:9182"
const strictModeAlphaGroup2 = "localhost:9183"

func runOn(conn *grpc.ClientConn, fn func(*testing.T, *dgo.Dgraph)) func(*testing.T) {
return func(t *testing.T) {
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
fn(t, dg)
}
}

func dropAllDisallowed(t *testing.T, dg *dgo.Dgraph) {
err := dg.Alter(context.Background(), &api.Operation{DropAll: true})

require.Error(t, err)
require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed")
}

func dropAllAllowed(t *testing.T, dg *dgo.Dgraph) {
err := dg.Alter(context.Background(), &api.Operation{DropAll: true})

require.NoError(t, err)
}

func mutateNewDisallowed(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

txn := dg.NewTxn()
_, err := txn.Mutate(ctx, &api.Mutation{
SetNquads: []byte(`
_:a <name> "Alice" .
`),
})

require.Error(t, err)
require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed")
}

func mutateNewDisallowed2(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

txn := dg.NewTxn()
_, err := txn.Mutate(ctx, &api.Mutation{
SetNquads: []byte(`
_:a <name> "Alice" .
`),
})

require.Error(t, err)
require.Contains(t, strings.ToLower(err.Error()), "schema not defined for predicate")
}

func addPredicateDisallowed(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

err := dg.Alter(ctx, &api.Operation{
Schema: `name: string @index(exact) .`,
})

require.Error(t, err)
require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed")
}

func addPredicateAllowed1(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

err := dg.Alter(ctx, &api.Operation{
Schema: `name: string @index(exact) .`,
})

require.NoError(t, err)
}

func addPredicateAllowed2(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

err := dg.Alter(ctx, &api.Operation{
Schema: `size: string @index(exact) .`,
})

require.NoError(t, err)
}

func mutateExistingDisallowed(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

txn := dg.NewTxn()
_, err := txn.Mutate(ctx, &api.Mutation{
SetNquads: []byte(`
_:a <dgraph.xid> "XID00001" .
`),
})

require.NoError(t, txn.Discard(ctx))
require.Error(t, err)
require.Contains(t, strings.ToLower(err.Error()), "no mutations allowed")
}

func mutateExistingAllowed1(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

txn := dg.NewTxn()
_, err := txn.Mutate(ctx, &api.Mutation{
SetNquads: []byte(`
_:a <name> "Alice" .
`),
})

require.NoError(t, txn.Commit(ctx))
require.NoError(t, err)
}

func mutateExistingAllowed2(t *testing.T, dg *dgo.Dgraph) {
ctx := context.Background()

txn := dg.NewTxn()
_, err := txn.Mutate(ctx, &api.Mutation{
SetNquads: []byte(`
_:s <size> "small" .
`),
})

require.NoError(t, txn.Commit(ctx))
require.NoError(t, err)
}

func TestMutationsDisallow(t *testing.T) {
conn, err := grpc.Dial(disallowModeAlpha, grpc.WithInsecure())
x.Check(err)
defer conn.Close()

t.Run("disallow drop all in no mutations mode",
runOn(conn, dropAllDisallowed))
t.Run("disallow mutate new predicate in no mutations mode",
runOn(conn, mutateNewDisallowed))
t.Run("disallow add predicate in no mutations mode",
runOn(conn, addPredicateDisallowed))
t.Run("disallow mutate existing predicate in no mutations mode",
runOn(conn, mutateExistingDisallowed))
}

func TestMutationsStrict(t *testing.T) {
conn1, err := grpc.Dial(strictModeAlphaGroup1, grpc.WithInsecure())
x.Check(err)
defer conn1.Close()

conn2, err := grpc.Dial(strictModeAlphaGroup2, grpc.WithInsecure())
x.Check(err)
defer conn2.Close()

t.Run("allow group1 drop all in strict mutations mode",
runOn(conn1, dropAllAllowed))
t.Run("allow group2 drop all in strict mutations mode",
runOn(conn2, dropAllAllowed))
t.Run("disallow group1 mutate new predicate in strict mutations mode",
runOn(conn1, mutateNewDisallowed2))
t.Run("disallow group2 mutate new predicate in strict mutations mode",
runOn(conn2, mutateNewDisallowed2))
t.Run("allow group1 add predicate in strict mutations mode",
runOn(conn1, addPredicateAllowed1))
t.Run("allow group2 add predicate in strict mutations mode",
runOn(conn2, addPredicateAllowed2))
t.Run("allow group1 mutate group1 predicate in strict mutations mode",
runOn(conn1, mutateExistingAllowed1))
t.Run("allow group2 mutate group1 predicate in strict mutations mode",
runOn(conn2, mutateExistingAllowed1))
t.Run("allow group1 mutate group2 predicate in strict mutations mode",
runOn(conn1, mutateExistingAllowed2))
t.Run("allow group2 mutate group2 predicate in strict mutations mode",
runOn(conn2, mutateExistingAllowed2))
}
32 changes: 0 additions & 32 deletions dgraph/cmd/alpha/nomutations/docker-compose.yml

This file was deleted.

Loading

0 comments on commit 976b498

Please sign in to comment.