| 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 // +build appengine | 5 // +build appengine |
| 6 | 6 |
| 7 package prod | 7 package prod |
| 8 | 8 |
| 9 import ( | 9 import ( |
| 10 "testing" | 10 "testing" |
| 11 "time" | 11 "time" |
| 12 | 12 |
| 13 "github.com/luci/gae/service/blobstore" | 13 "github.com/luci/gae/service/blobstore" |
| 14 » "github.com/luci/gae/service/datastore" | 14 » ds "github.com/luci/gae/service/datastore" |
| 15 "github.com/luci/gae/service/info" | 15 "github.com/luci/gae/service/info" |
| 16 » "github.com/luci/gae/service/memcache" | 16 » mc "github.com/luci/gae/service/memcache" |
| 17 |
| 17 "github.com/luci/luci-go/common/logging" | 18 "github.com/luci/luci-go/common/logging" |
| 18 » . "github.com/smartystreets/goconvey/convey" | 19 |
| 19 "golang.org/x/net/context" | 20 "golang.org/x/net/context" |
| 20 "google.golang.org/appengine/aetest" | 21 "google.golang.org/appengine/aetest" |
| 22 |
| 23 . "github.com/smartystreets/goconvey/convey" |
| 21 ) | 24 ) |
| 22 | 25 |
| 23 var ( | 26 var ( |
| 24 » mp = datastore.MkProperty | 27 » mp = ds.MkProperty |
| 25 » mpNI = datastore.MkPropertyNI | 28 » mpNI = ds.MkPropertyNI |
| 26 ) | 29 ) |
| 27 | 30 |
| 28 type TestStruct struct { | 31 type TestStruct struct { |
| 29 ID int64 `gae:"$id"` | 32 ID int64 `gae:"$id"` |
| 30 | 33 |
| 31 ValueI []int64 | 34 ValueI []int64 |
| 32 ValueB []bool | 35 ValueB []bool |
| 33 ValueS []string | 36 ValueS []string |
| 34 ValueF []float64 | 37 ValueF []float64 |
| 35 ValueBS [][]byte // "ByteString" | 38 ValueBS [][]byte // "ByteString" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 47 inst, err := aetest.NewInstance(&aetest.Options{ | 50 inst, err := aetest.NewInstance(&aetest.Options{ |
| 48 StronglyConsistentDatastore: true, | 51 StronglyConsistentDatastore: true, |
| 49 }) | 52 }) |
| 50 So(err, ShouldBeNil) | 53 So(err, ShouldBeNil) |
| 51 defer inst.Close() | 54 defer inst.Close() |
| 52 | 55 |
| 53 req, err := inst.NewRequest("GET", "/", nil) | 56 req, err := inst.NewRequest("GET", "/", nil) |
| 54 So(err, ShouldBeNil) | 57 So(err, ShouldBeNil) |
| 55 | 58 |
| 56 ctx := Use(context.Background(), req) | 59 ctx := Use(context.Background(), req) |
| 57 ds := datastore.Get(ctx) | |
| 58 mc := memcache.Get(ctx) | |
| 59 inf := info.Get(ctx) | |
| 60 | 60 |
| 61 Convey("logging allows you to tweak the level", func() { | 61 Convey("logging allows you to tweak the level", func() { |
| 62 // You have to visually confirm that this actually happe
ns in the stdout | 62 // You have to visually confirm that this actually happe
ns in the stdout |
| 63 // of the test... yeah I know. | 63 // of the test... yeah I know. |
| 64 logging.Debugf(ctx, "SHOULD NOT SEE") | 64 logging.Debugf(ctx, "SHOULD NOT SEE") |
| 65 logging.Infof(ctx, "SHOULD SEE") | 65 logging.Infof(ctx, "SHOULD SEE") |
| 66 | 66 |
| 67 ctx = logging.SetLevel(ctx, logging.Debug) | 67 ctx = logging.SetLevel(ctx, logging.Debug) |
| 68 logging.Debugf(ctx, "SHOULD SEE") | 68 logging.Debugf(ctx, "SHOULD SEE") |
| 69 logging.Infof(ctx, "SHOULD SEE (2)") | 69 logging.Infof(ctx, "SHOULD SEE (2)") |
| 70 }) | 70 }) |
| 71 | 71 |
| 72 Convey("Can probe/change Namespace", func() { | 72 Convey("Can probe/change Namespace", func() { |
| 73 » » » ns, has := inf.GetNamespace() | 73 » » » So(info.GetNamespace(ctx), ShouldEqual, "") |
| 74 » » » So(ns, ShouldEqual, "") | |
| 75 » » » So(has, ShouldBeFalse) | |
| 76 | 74 |
| 77 » » » ctx, err = inf.Namespace("wat") | 75 » » » ctx, err = info.Namespace(ctx, "wat") |
| 78 So(err, ShouldBeNil) | 76 So(err, ShouldBeNil) |
| 79 inf = info.Get(ctx) | |
| 80 | 77 |
| 81 » » » ns, has = inf.GetNamespace() | 78 » » » So(info.GetNamespace(ctx), ShouldEqual, "wat") |
| 82 » » » So(ns, ShouldEqual, "wat") | 79 » » » So(ds.MakeKey(ctx, "Hello", "world").Namespace(), Should
Equal, "wat") |
| 83 » » » So(has, ShouldBeTrue) | |
| 84 | |
| 85 » » » ds = datastore.Get(ctx) | |
| 86 » » » So(ds.MakeKey("Hello", "world").Namespace(), ShouldEqual
, "wat") | |
| 87 }) | 80 }) |
| 88 | 81 |
| 89 Convey("Can get non-transactional context", func() { | 82 Convey("Can get non-transactional context", func() { |
| 90 » » » ctx, err := inf.Namespace("foo") | 83 » » » ctx, err := info.Namespace(ctx, "foo") |
| 91 So(err, ShouldBeNil) | 84 So(err, ShouldBeNil) |
| 92 ds = datastore.Get(ctx) | |
| 93 inf = info.Get(ctx) | |
| 94 | 85 |
| 95 » » » ds.RunInTransaction(func(ctx context.Context) error { | 86 » » » So(ds.CurrentTransaction(ctx), ShouldBeNil) |
| 96 » » » » So(ds.MakeKey("Foo", "bar").Namespace(), ShouldE
qual, "foo") | |
| 97 | 87 |
| 98 » » » » So(ds.Put(&TestStruct{ValueI: []int64{100}}), Sh
ouldBeNil) | 88 » » » ds.RunInTransaction(ctx, func(ctx context.Context) error
{ |
| 89 » » » » So(ds.CurrentTransaction(ctx), ShouldNotBeNil) |
| 90 » » » » So(ds.MakeKey(ctx, "Foo", "bar").Namespace(), Sh
ouldEqual, "foo") |
| 99 | 91 |
| 100 » » » » err = datastore.GetNoTxn(ctx).RunInTransaction(f
unc(ctx context.Context) error { | 92 » » » » So(ds.Put(ctx, &TestStruct{ValueI: []int64{100}}
), ShouldBeNil) |
| 101 » » » » » ds = datastore.Get(ctx) | 93 |
| 102 » » » » » So(ds.MakeKey("Foo", "bar").Namespace(),
ShouldEqual, "foo") | 94 » » » » noTxnCtx := ds.WithoutTransaction(ctx) |
| 103 » » » » » So(ds.Put(&TestStruct{ValueI: []int64{10
0}}), ShouldBeNil) | 95 » » » » So(ds.CurrentTransaction(noTxnCtx), ShouldBeNil) |
| 96 |
| 97 » » » » err = ds.RunInTransaction(noTxnCtx, func(ctx con
text.Context) error { |
| 98 » » » » » So(ds.CurrentTransaction(ctx), ShouldNot
BeNil) |
| 99 » » » » » So(ds.MakeKey(ctx, "Foo", "bar").Namespa
ce(), ShouldEqual, "foo") |
| 100 » » » » » So(ds.Put(ctx, &TestStruct{ValueI: []int
64{100}}), ShouldBeNil) |
| 104 return nil | 101 return nil |
| 105 }, nil) | 102 }, nil) |
| 106 So(err, ShouldBeNil) | 103 So(err, ShouldBeNil) |
| 107 | 104 |
| 108 return nil | 105 return nil |
| 109 }, nil) | 106 }, nil) |
| 110 }) | 107 }) |
| 111 | 108 |
| 112 Convey("Can Put/Get", func() { | 109 Convey("Can Put/Get", func() { |
| 113 orig := TestStruct{ | 110 orig := TestStruct{ |
| 114 ValueI: []int64{1, 7, 946688461000000, 996688461
000000}, | 111 ValueI: []int64{1, 7, 946688461000000, 996688461
000000}, |
| 115 ValueB: []bool{true, false}, | 112 ValueB: []bool{true, false}, |
| 116 ValueS: []string{"hello", "world"}, | 113 ValueS: []string{"hello", "world"}, |
| 117 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
96688461000000.0}, | 114 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
96688461000000.0}, |
| 118 ValueBS: [][]byte{ | 115 ValueBS: [][]byte{ |
| 119 []byte("allo"), | 116 []byte("allo"), |
| 120 []byte("hello"), | 117 []byte("hello"), |
| 121 []byte("world"), | 118 []byte("world"), |
| 122 []byte("zurple"), | 119 []byte("zurple"), |
| 123 }, | 120 }, |
| 124 » » » » ValueK: []*datastore.Key{ | 121 » » » » ValueK: []*ds.Key{ |
| 125 » » » » » ds.NewKey("Something", "Cool", 0, nil), | 122 » » » » » ds.NewKey(ctx, "Something", "Cool", 0, n
il), |
| 126 » » » » » ds.NewKey("Something", "", 1, nil), | 123 » » » » » ds.NewKey(ctx, "Something", "", 1, nil), |
| 127 » » » » » ds.NewKey("Something", "Recursive", 0, | 124 » » » » » ds.NewKey(ctx, "Something", "Recursive",
0, |
| 128 » » » » » » ds.NewKey("Parent", "", 2, nil))
, | 125 » » » » » » ds.NewKey(ctx, "Parent", "", 2,
nil)), |
| 129 }, | 126 }, |
| 130 ValueBK: []blobstore.Key{"bellow", "hello"}, | 127 ValueBK: []blobstore.Key{"bellow", "hello"}, |
| 131 » » » » ValueGP: []datastore.GeoPoint{ | 128 » » » » ValueGP: []ds.GeoPoint{ |
| 132 {Lat: 120.7, Lng: 95.5}, | 129 {Lat: 120.7, Lng: 95.5}, |
| 133 }, | 130 }, |
| 134 ValueSingle: "ohai", | 131 ValueSingle: "ohai", |
| 135 ValueSingleSlice: []string{"kthxbye"}, | 132 ValueSingleSlice: []string{"kthxbye"}, |
| 136 } | 133 } |
| 137 » » » So(ds.Put(&orig), ShouldBeNil) | 134 » » » So(ds.Put(ctx, &orig), ShouldBeNil) |
| 138 | 135 |
| 139 ret := TestStruct{ID: orig.ID} | 136 ret := TestStruct{ID: orig.ID} |
| 140 » » » So(ds.Get(&ret), ShouldBeNil) | 137 » » » So(ds.Get(ctx, &ret), ShouldBeNil) |
| 141 So(ret, ShouldResemble, orig) | 138 So(ret, ShouldResemble, orig) |
| 142 | 139 |
| 143 // make sure single- and multi- properties are preserved
. | 140 // make sure single- and multi- properties are preserved
. |
| 144 pmap := datastore.PropertyMap{ | 141 pmap := datastore.PropertyMap{ |
| 145 "$id": mpNI(orig.ID), | 142 "$id": mpNI(orig.ID), |
| 146 "$kind": mpNI("TestStruct"), | 143 "$kind": mpNI("TestStruct"), |
| 147 } | 144 } |
| 148 So(ds.Get(pmap), ShouldBeNil) | 145 So(ds.Get(pmap), ShouldBeNil) |
| 149 So(pmap["ValueSingle"], ShouldHaveSameTypeAs, datastore.
Property{}) | 146 So(pmap["ValueSingle"], ShouldHaveSameTypeAs, datastore.
Property{}) |
| 150 So(pmap["ValueSingleSlice"], ShouldHaveSameTypeAs, datas
tore.PropertySlice(nil)) | 147 So(pmap["ValueSingleSlice"], ShouldHaveSameTypeAs, datas
tore.PropertySlice(nil)) |
| 151 | 148 |
| 152 // can't be sure the indexes have caught up... so sleep | 149 // can't be sure the indexes have caught up... so sleep |
| 153 time.Sleep(time.Second) | 150 time.Sleep(time.Second) |
| 154 | 151 |
| 155 Convey("Can query", func() { | 152 Convey("Can query", func() { |
| 156 » » » » q := datastore.NewQuery("TestStruct") | 153 » » » » q := ds.NewQuery("TestStruct") |
| 157 » » » » ds.Run(q, func(ts *TestStruct) { | 154 » » » » ds.Run(ctx, q, func(ts *TestStruct) { |
| 158 So(*ts, ShouldResemble, orig) | 155 So(*ts, ShouldResemble, orig) |
| 159 }) | 156 }) |
| 160 » » » » count, err := ds.Count(q) | 157 » » » » count, err := ds.Count(ctx, q) |
| 161 So(err, ShouldBeNil) | 158 So(err, ShouldBeNil) |
| 162 So(count, ShouldEqual, 1) | 159 So(count, ShouldEqual, 1) |
| 163 }) | 160 }) |
| 164 | 161 |
| 165 Convey("Can project", func() { | 162 Convey("Can project", func() { |
| 166 » » » » q := datastore.NewQuery("TestStruct").Project("V
alueS") | 163 » » » » q := ds.NewQuery("TestStruct").Project("ValueS") |
| 167 » » » » rslts := []datastore.PropertyMap{} | 164 » » » » rslts := []ds.PropertyMap{} |
| 168 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) | 165 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil) |
| 169 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa
p{ | 166 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{ |
| 170 { | 167 { |
| 171 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 168 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 172 "ValueS": mp("hello"), | 169 "ValueS": mp("hello"), |
| 173 }, | 170 }, |
| 174 { | 171 { |
| 175 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 172 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 176 "ValueS": mp("world"), | 173 "ValueS": mp("world"), |
| 177 }, | 174 }, |
| 178 }) | 175 }) |
| 179 | 176 |
| 180 » » » » q = datastore.NewQuery("TestStruct").Project("Va
lueBS") | 177 » » » » q = ds.NewQuery("TestStruct").Project("ValueBS") |
| 181 » » » » rslts = []datastore.PropertyMap{} | 178 » » » » rslts = []ds.PropertyMap{} |
| 182 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) | 179 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil) |
| 183 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa
p{ | 180 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{ |
| 184 { | 181 { |
| 185 » » » » » » "$key": mpNI(ds.KeyForObj(&or
ig)), | 182 » » » » » » "$key": mpNI(ds.KeyForObj(ctx
, &orig)), |
| 186 "ValueBS": mp("allo"), | 183 "ValueBS": mp("allo"), |
| 187 }, | 184 }, |
| 188 { | 185 { |
| 189 » » » » » » "$key": mpNI(ds.KeyForObj(&or
ig)), | 186 » » » » » » "$key": mpNI(ds.KeyForObj(ctx
, &orig)), |
| 190 "ValueBS": mp("hello"), | 187 "ValueBS": mp("hello"), |
| 191 }, | 188 }, |
| 192 { | 189 { |
| 193 » » » » » » "$key": mpNI(ds.KeyForObj(&or
ig)), | 190 » » » » » » "$key": mpNI(ds.KeyForObj(ctx
, &orig)), |
| 194 "ValueBS": mp("world"), | 191 "ValueBS": mp("world"), |
| 195 }, | 192 }, |
| 196 { | 193 { |
| 197 » » » » » » "$key": mpNI(ds.KeyForObj(&or
ig)), | 194 » » » » » » "$key": mpNI(ds.KeyForObj(ctx
, &orig)), |
| 198 "ValueBS": mp("zurple"), | 195 "ValueBS": mp("zurple"), |
| 199 }, | 196 }, |
| 200 }) | 197 }) |
| 201 | 198 |
| 202 » » » » count, err := ds.Count(q) | 199 » » » » count, err := ds.Count(ctx, q) |
| 203 So(err, ShouldBeNil) | 200 So(err, ShouldBeNil) |
| 204 So(count, ShouldEqual, 4) | 201 So(count, ShouldEqual, 4) |
| 205 | 202 |
| 206 » » » » q = datastore.NewQuery("TestStruct").Lte("ValueI
", 7).Project("ValueS").Distinct(true) | 203 » » » » q = ds.NewQuery("TestStruct").Lte("ValueI", 7).P
roject("ValueS").Distinct(true) |
| 207 » » » » rslts = []datastore.PropertyMap{} | 204 » » » » rslts = []ds.PropertyMap{} |
| 208 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) | 205 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil) |
| 209 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa
p{ | 206 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{ |
| 210 { | 207 { |
| 211 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 208 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 212 "ValueI": mp(1), | 209 "ValueI": mp(1), |
| 213 "ValueS": mp("hello"), | 210 "ValueS": mp("hello"), |
| 214 }, | 211 }, |
| 215 { | 212 { |
| 216 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 213 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 217 "ValueI": mp(1), | 214 "ValueI": mp(1), |
| 218 "ValueS": mp("world"), | 215 "ValueS": mp("world"), |
| 219 }, | 216 }, |
| 220 { | 217 { |
| 221 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 218 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 222 "ValueI": mp(7), | 219 "ValueI": mp(7), |
| 223 "ValueS": mp("hello"), | 220 "ValueS": mp("hello"), |
| 224 }, | 221 }, |
| 225 { | 222 { |
| 226 » » » » » » "$key": mpNI(ds.KeyForObj(&ori
g)), | 223 » » » » » » "$key": mpNI(ds.KeyForObj(ctx,
&orig)), |
| 227 "ValueI": mp(7), | 224 "ValueI": mp(7), |
| 228 "ValueS": mp("world"), | 225 "ValueS": mp("world"), |
| 229 }, | 226 }, |
| 230 }) | 227 }) |
| 231 | 228 |
| 232 » » » » count, err = ds.Count(q) | 229 » » » » count, err = ds.Count(ctx, q) |
| 233 So(err, ShouldBeNil) | 230 So(err, ShouldBeNil) |
| 234 So(count, ShouldEqual, 4) | 231 So(count, ShouldEqual, 4) |
| 235 }) | 232 }) |
| 236 }) | 233 }) |
| 237 | 234 |
| 238 Convey("Can Put/Get (time)", func() { | 235 Convey("Can Put/Get (time)", func() { |
| 239 // time comparisons in Go are wonky, so this is pulled o
ut | 236 // time comparisons in Go are wonky, so this is pulled o
ut |
| 240 pm := datastore.PropertyMap{ | 237 pm := datastore.PropertyMap{ |
| 241 » » » » "$key": mpNI(ds.NewKey("Something", "value", 0,
nil)), | 238 » » » » "$key": mpNI(ds.NewKey(ctx, "Something", "value"
, 0, nil)), |
| 242 "Time": datastore.PropertySlice{ | 239 "Time": datastore.PropertySlice{ |
| 243 mp(time.Date(1938, time.January, 1, 1, 1
, 1, 1, time.UTC)), | 240 mp(time.Date(1938, time.January, 1, 1, 1
, 1, 1, time.UTC)), |
| 244 mp(time.Time{}), | 241 mp(time.Time{}), |
| 245 }, | 242 }, |
| 246 } | 243 } |
| 247 » » » So(ds.Put(&pm), ShouldBeNil) | 244 » » » So(ds.Put(ctx, &pm), ShouldBeNil) |
| 248 | 245 |
| 249 » » » rslt := datastore.PropertyMap{} | 246 » » » rslt := ds.PropertyMap{} |
| 250 » » » rslt.SetMeta("key", ds.KeyForObj(pm)) | 247 » » » rslt.SetMeta("key", ds.KeyForObj(ctx, pm)) |
| 251 » » » So(ds.Get(&rslt), ShouldBeNil) | 248 » » » So(ds.Get(ctx, &rslt), ShouldBeNil) |
| 252 | 249 |
| 253 So(pm.Slice("Time")[0].Value(), ShouldResemble, rslt.Sli
ce("Time")[0].Value()) | 250 So(pm.Slice("Time")[0].Value(), ShouldResemble, rslt.Sli
ce("Time")[0].Value()) |
| 254 | 251 |
| 255 » » » q := datastore.NewQuery("Something").Project("Time") | 252 » » » q := ds.NewQuery("Something").Project("Time") |
| 256 » » » all := []datastore.PropertyMap{} | 253 » » » all := []ds.PropertyMap{} |
| 257 » » » So(ds.GetAll(q, &all), ShouldBeNil) | 254 » » » So(ds.GetAll(ctx, q, &all), ShouldBeNil) |
| 258 So(len(all), ShouldEqual, 2) | 255 So(len(all), ShouldEqual, 2) |
| 259 prop := all[0].Slice("Time")[0] | 256 prop := all[0].Slice("Time")[0] |
| 260 So(prop.Type(), ShouldEqual, datastore.PTInt) | 257 So(prop.Type(), ShouldEqual, datastore.PTInt) |
| 261 | 258 |
| 262 » » » tval, err := prop.Project(datastore.PTTime) | 259 » » » tval, err := prop.Project(ds.PTTime) |
| 263 So(err, ShouldBeNil) | 260 So(err, ShouldBeNil) |
| 264 So(tval, ShouldResemble, time.Time{}.UTC()) | 261 So(tval, ShouldResemble, time.Time{}.UTC()) |
| 265 | 262 |
| 266 tval, err = all[1].Slice("Time")[0].Project(datastore.PT
Time) | 263 tval, err = all[1].Slice("Time")[0].Project(datastore.PT
Time) |
| 267 So(err, ShouldBeNil) | 264 So(err, ShouldBeNil) |
| 268 So(tval, ShouldResemble, pm.Slice("Time")[0].Value()) | 265 So(tval, ShouldResemble, pm.Slice("Time")[0].Value()) |
| 269 | 266 |
| 270 ent := datastore.PropertyMap{ | 267 ent := datastore.PropertyMap{ |
| 271 » » » » "$key": mpNI(ds.MakeKey("Something", "value")), | 268 » » » » "$key": mpNI(ds.MakeKey(ctx, "Something", "value
")), |
| 272 } | 269 } |
| 273 » » » So(ds.Get(&ent), ShouldBeNil) | 270 » » » So(ds.Get(ctx, &ent), ShouldBeNil) |
| 274 So(ent["Time"], ShouldResemble, pm["Time"]) | 271 So(ent["Time"], ShouldResemble, pm["Time"]) |
| 275 }) | 272 }) |
| 276 | 273 |
| 277 Convey("memcache: Set (nil) is the same as Set ([]byte{})", func
() { | 274 Convey("memcache: Set (nil) is the same as Set ([]byte{})", func
() { |
| 278 » » » So(mc.Set(mc.NewItem("bob")), ShouldBeNil) // normally w
ould panic because Value is nil | 275 » » » So(mc.Set(ctx, mc.NewItem(ctx, "bob")), ShouldBeNil) //
normally would panic because Value is nil |
| 279 | 276 |
| 280 » » » bob, err := mc.Get("bob") | 277 » » » bob, err := mc.GetKey(ctx, "bob") |
| 281 So(err, ShouldBeNil) | 278 So(err, ShouldBeNil) |
| 282 So(bob.Value(), ShouldResemble, []byte{}) | 279 So(bob.Value(), ShouldResemble, []byte{}) |
| 283 }) | 280 }) |
| 284 }) | 281 }) |
| 285 } | 282 } |
| OLD | NEW |