OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The LUCI Authors. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 package readonly |
| 16 |
| 17 import ( |
| 18 "testing" |
| 19 |
| 20 "github.com/luci/gae/impl/memory" |
| 21 ds "github.com/luci/gae/service/datastore" |
| 22 |
| 23 "github.com/luci/luci-go/common/errors" |
| 24 |
| 25 "golang.org/x/net/context" |
| 26 |
| 27 . "github.com/smartystreets/goconvey/convey" |
| 28 ) |
| 29 |
| 30 func TestReadOnly(t *testing.T) { |
| 31 t.Parallel() |
| 32 |
| 33 Convey("Test datastore filter", t, func() { |
| 34 c := memory.Use(context.Background()) |
| 35 |
| 36 type Tester struct { |
| 37 ID int `gae:"$id"` |
| 38 Value string |
| 39 } |
| 40 |
| 41 // Add a value to the datastore before applying the filter. |
| 42 ds.Put(c, &Tester{ID: 1, Value: "exists"}) |
| 43 ds.GetTestable(c).CatchupIndexes() |
| 44 |
| 45 // Apply the read-only filter. |
| 46 c = FilterRDS(c) |
| 47 So(c, ShouldNotBeNil) |
| 48 |
| 49 Convey("Get works.", func() { |
| 50 v := Tester{ID: 1} |
| 51 So(ds.Get(c, &v), ShouldBeNil) |
| 52 So(v.Value, ShouldEqual, "exists") |
| 53 }) |
| 54 |
| 55 Convey("Count works.", func() { |
| 56 q := ds.NewQuery("Tester") |
| 57 cnt, err := ds.Count(c, q) |
| 58 So(err, ShouldBeNil) |
| 59 So(cnt, ShouldEqual, 1) |
| 60 }) |
| 61 |
| 62 Convey("Put fails with read-only error", func() { |
| 63 So(ds.Put(c, &Tester{ID: 2}), ShouldEqual, ErrReadOnly) |
| 64 }) |
| 65 |
| 66 Convey("Delete fails with read-only error", func() { |
| 67 So(ds.Delete(c, &Tester{ID: 2}), ShouldEqual, ErrReadOnl
y) |
| 68 }) |
| 69 |
| 70 Convey("AllocateIDs fails with read-only error", func() { |
| 71 err := ds.AllocateIDs(c, make([]Tester, 10)) |
| 72 So(err, ShouldNotBeNil) |
| 73 So(errors.SingleError(err), ShouldEqual, ErrReadOnly) |
| 74 }) |
| 75 |
| 76 Convey("In a transaction", func() { |
| 77 Convey("Get works.", func() { |
| 78 v := Tester{ID: 1} |
| 79 |
| 80 err := ds.RunInTransaction(c, func(c context.Con
text) error { |
| 81 return ds.Get(c, &v) |
| 82 }, nil) |
| 83 So(err, ShouldBeNil) |
| 84 So(v.Value, ShouldEqual, "exists") |
| 85 }) |
| 86 |
| 87 Convey("Count works.", func() { |
| 88 // (Need ancestor filter for transaction query) |
| 89 q := ds.NewQuery("Tester").Ancestor(ds.KeyForObj
(c, &Tester{ID: 1})) |
| 90 |
| 91 var cnt int64 |
| 92 err := ds.RunInTransaction(c, func(c context.Con
text) (err error) { |
| 93 cnt, err = ds.Count(c, q) |
| 94 return |
| 95 }, nil) |
| 96 So(err, ShouldBeNil) |
| 97 So(cnt, ShouldEqual, 1) |
| 98 }) |
| 99 |
| 100 Convey("Put fails with read-only error", func() { |
| 101 err := ds.RunInTransaction(c, func(c context.Con
text) error { |
| 102 return ds.Put(c, &Tester{ID: 2}) |
| 103 }, nil) |
| 104 So(err, ShouldEqual, ErrReadOnly) |
| 105 }) |
| 106 |
| 107 Convey("Delete fails with read-only error", func() { |
| 108 err := ds.RunInTransaction(c, func(c context.Con
text) error { |
| 109 return ds.Delete(c, &Tester{ID: 2}) |
| 110 }, nil) |
| 111 So(err, ShouldEqual, ErrReadOnly) |
| 112 }) |
| 113 |
| 114 Convey("AllocateIDs fails with read-only error", func()
{ |
| 115 err := ds.RunInTransaction(c, func(c context.Con
text) error { |
| 116 return ds.AllocateIDs(c, make([]Tester,
10)) |
| 117 }, nil) |
| 118 So(err, ShouldNotBeNil) |
| 119 So(errors.SingleError(err), ShouldEqual, ErrRead
Only) |
| 120 }) |
| 121 }) |
| 122 }) |
| 123 } |
OLD | NEW |