OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "testing" | 9 "testing" |
10 | 10 |
11 dstore "github.com/luci/gae/service/datastore" | 11 dstore "github.com/luci/gae/service/datastore" |
12 "github.com/luci/gae/service/datastore/serialize" | 12 "github.com/luci/gae/service/datastore/serialize" |
| 13 |
13 "github.com/luci/luci-go/common/data/cmpbin" | 14 "github.com/luci/luci-go/common/data/cmpbin" |
14 "github.com/luci/luci-go/common/data/stringset" | 15 "github.com/luci/luci-go/common/data/stringset" |
| 16 |
15 . "github.com/luci/luci-go/common/testing/assertions" | 17 . "github.com/luci/luci-go/common/testing/assertions" |
16 . "github.com/smartystreets/goconvey/convey" | 18 . "github.com/smartystreets/goconvey/convey" |
17 ) | 19 ) |
18 | 20 |
19 type sillyCursor string | 21 type sillyCursor string |
20 | 22 |
21 func (s sillyCursor) String() string { return string(s) } | 23 func (s sillyCursor) String() string { return string(s) } |
22 | 24 |
23 func curs(pairs ...interface{}) queryCursor { | 25 func curs(pairs ...interface{}) queryCursor { |
24 if len(pairs)%2 != 0 { | 26 if len(pairs)%2 != 0 { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 {"silly inequality (=> v <=)", | 111 {"silly inequality (=> v <=)", |
110 nq().Gte("bob", 10).Lte("bob", 10), | 112 nq().Gte("bob", 10).Lte("bob", 10), |
111 nil, nil}, | 113 nil, nil}, |
112 | 114 |
113 {"cursors get smooshed into the inquality range", | 115 {"cursors get smooshed into the inquality range", |
114 (nq().Gt("Foo", 3).Lt("Foo", 10). | 116 (nq().Gt("Foo", 3).Lt("Foo", 10). |
115 Start(curs("Foo", 2, "__key__", key("Something", 1))). | 117 Start(curs("Foo", 2, "__key__", key("Something", 1))). |
116 End(curs("Foo", 20, "__key__", key("Something", 20)))), | 118 End(curs("Foo", 20, "__key__", key("Something", 20)))), |
117 nil, | 119 nil, |
118 &reducedQuery{ | 120 &reducedQuery{ |
119 » » » "dev~app", "ns", "Foo", map[string]stringset.Set{}, []ds
tore.IndexColumn{ | 121 » » » dstore.KeyContext{"dev~app", "ns"}, |
| 122 » » » "Foo", map[string]stringset.Set{}, []dstore.IndexColumn{ |
120 {Property: "Foo"}, | 123 {Property: "Foo"}, |
121 {Property: "__key__"}, | 124 {Property: "__key__"}, |
122 }, | 125 }, |
123 increment(serialize.ToBytes(dstore.MkProperty(3))), | 126 increment(serialize.ToBytes(dstore.MkProperty(3))), |
124 serialize.ToBytes(dstore.MkProperty(10)), | 127 serialize.ToBytes(dstore.MkProperty(10)), |
125 2, | 128 2, |
126 }}, | 129 }}, |
127 | 130 |
128 {"cursors could cause the whole query to be useless", | 131 {"cursors could cause the whole query to be useless", |
129 (nq().Gt("Foo", 3).Lt("Foo", 10). | 132 (nq().Gt("Foo", 3).Lt("Foo", 10). |
130 Start(curs("Foo", 200, "__key__", key("Something", 1))). | 133 Start(curs("Foo", 200, "__key__", key("Something", 1))). |
131 End(curs("Foo", 1, "__key__", key("Something", 20)))), | 134 End(curs("Foo", 1, "__key__", key("Something", 20)))), |
132 dstore.ErrNullQuery, | 135 dstore.ErrNullQuery, |
133 nil}, | 136 nil}, |
134 } | 137 } |
135 | 138 |
136 func TestQueries(t *testing.T) { | 139 func TestQueries(t *testing.T) { |
137 t.Parallel() | 140 t.Parallel() |
138 | 141 |
139 Convey("queries have tons of condition checking", t, func() { | 142 Convey("queries have tons of condition checking", t, func() { |
| 143 kc := dstore.KeyContext{"dev~app", "ns"} |
| 144 |
140 Convey("non-ancestor queries in a transaction", func() { | 145 Convey("non-ancestor queries in a transaction", func() { |
141 fq, err := nq().Finalize() | 146 fq, err := nq().Finalize() |
142 So(err, ShouldErrLike, nil) | 147 So(err, ShouldErrLike, nil) |
143 » » » _, err = reduce(fq, "dev~app", "ns", true) | 148 » » » _, err = reduce(fq, kc, true) |
144 So(err, ShouldErrLike, "must include an Ancestor") | 149 So(err, ShouldErrLike, "must include an Ancestor") |
145 }) | 150 }) |
146 | 151 |
147 Convey("absurd numbers of filters are prohibited", func() { | 152 Convey("absurd numbers of filters are prohibited", func() { |
148 q := nq().Ancestor(key("thing", "wat")) | 153 q := nq().Ancestor(key("thing", "wat")) |
149 for i := 0; i < 100; i++ { | 154 for i := 0; i < 100; i++ { |
150 q = q.Eq("something", i) | 155 q = q.Eq("something", i) |
151 } | 156 } |
152 fq, err := q.Finalize() | 157 fq, err := q.Finalize() |
153 So(err, ShouldErrLike, nil) | 158 So(err, ShouldErrLike, nil) |
154 » » » _, err = reduce(fq, "dev~app", "ns", false) | 159 » » » _, err = reduce(fq, kc, false) |
155 So(err, ShouldErrLike, "query is too large") | 160 So(err, ShouldErrLike, "query is too large") |
156 }) | 161 }) |
157 | 162 |
158 Convey("bulk check", func() { | 163 Convey("bulk check", func() { |
159 for _, tc := range queryTests { | 164 for _, tc := range queryTests { |
160 Convey(tc.name, func() { | 165 Convey(tc.name, func() { |
161 rq := (*reducedQuery)(nil) | 166 rq := (*reducedQuery)(nil) |
162 fq, err := tc.q.Finalize() | 167 fq, err := tc.q.Finalize() |
163 if err == nil { | 168 if err == nil { |
164 » » » » » » err = fq.Valid("s~aid", "ns") | 169 » » » » » » err = fq.Valid(kc) |
165 if err == nil { | 170 if err == nil { |
166 » » » » » » » rq, err = reduce(fq, "de
v~app", "ns", false) | 171 » » » » » » » rq, err = reduce(fq, kc,
false) |
167 } | 172 } |
168 } | 173 } |
169 So(err, ShouldErrLike, tc.err) | 174 So(err, ShouldErrLike, tc.err) |
170 | 175 |
171 if tc.equivalentQuery != nil { | 176 if tc.equivalentQuery != nil { |
172 So(rq, ShouldResemble, tc.equiva
lentQuery) | 177 So(rq, ShouldResemble, tc.equiva
lentQuery) |
173 } | 178 } |
174 }) | 179 }) |
175 } | 180 } |
176 }) | 181 }) |
177 }) | 182 }) |
178 } | 183 } |
OLD | NEW |