| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // 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 »       dstore "github.com/luci/gae/service/datastore" |   14 »       "github.com/luci/gae/service/datastore" | 
 |   15 »       "github.com/luci/gae/service/info" | 
|   15         . "github.com/smartystreets/goconvey/convey" |   16         . "github.com/smartystreets/goconvey/convey" | 
 |   17         "golang.org/x/net/context" | 
|   16         "google.golang.org/appengine/aetest" |   18         "google.golang.org/appengine/aetest" | 
|   17 ) |   19 ) | 
|   18  |   20  | 
|   19 var ( |   21 var ( | 
|   20 »       mp   = dstore.MkProperty |   22 »       mp   = datastore.MkProperty | 
|   21 »       mpNI = dstore.MkPropertyNI |   23 »       mpNI = datastore.MkPropertyNI | 
|   22 ) |   24 ) | 
|   23  |   25  | 
|   24 type TestStruct struct { |   26 type TestStruct struct { | 
|   25         ID int64 `gae:"$id"` |   27         ID int64 `gae:"$id"` | 
|   26  |   28  | 
|   27         ValueI  []int64 |   29         ValueI  []int64 | 
|   28         ValueB  []bool |   30         ValueB  []bool | 
|   29         ValueS  []string |   31         ValueS  []string | 
|   30         ValueF  []float64 |   32         ValueF  []float64 | 
|   31         ValueBS [][]byte // "ByteString" |   33         ValueBS [][]byte // "ByteString" | 
|   32 »       ValueK  []*dstore.Key |   34 »       ValueK  []*datastore.Key | 
|   33         ValueBK []blobstore.Key |   35         ValueBK []blobstore.Key | 
|   34 »       ValueGP []dstore.GeoPoint |   36 »       ValueGP []datastore.GeoPoint | 
|   35 } |   37 } | 
|   36  |   38  | 
|   37 func TestBasicDatastore(t *testing.T) { |   39 func TestBasicDatastore(t *testing.T) { | 
|   38         t.Parallel() |   40         t.Parallel() | 
|   39  |   41  | 
|   40         Convey("basic", t, func() { |   42         Convey("basic", t, func() { | 
|   41 »       »       ctx, closer, err := aetest.NewContext() |   43 »       »       inst, err := aetest.NewInstance(&aetest.Options{ | 
 |   44 »       »       »       StronglyConsistentDatastore: true, | 
 |   45 »       »       }) | 
|   42                 So(err, ShouldBeNil) |   46                 So(err, ShouldBeNil) | 
|   43 »       »       defer closer() |   47 »       »       defer inst.Close() | 
|   44  |   48  | 
|   45 »       »       ctx = Use(ctx) |   49 »       »       req, err := inst.NewRequest("GET", "/", nil) | 
|   46 »       »       ds := dstore.Get(ctx) |   50 »       »       So(err, ShouldBeNil) | 
 |   51  | 
 |   52 »       »       ctx := Use(context.Background(), req) | 
 |   53 »       »       ds := datastore.Get(ctx) | 
 |   54 »       »       inf := info.Get(ctx) | 
 |   55  | 
 |   56 »       »       Convey("Can probe/change Namespace", func() { | 
 |   57 »       »       »       So(inf.GetNamespace(), ShouldEqual, "") | 
 |   58 »       »       »       ctx, err = inf.Namespace("wat") | 
 |   59 »       »       »       So(err, ShouldBeNil) | 
 |   60 »       »       »       inf = info.Get(ctx) | 
 |   61 »       »       »       So(inf.GetNamespace(), ShouldEqual, "wat") | 
 |   62 »       »       »       ds = datastore.Get(ctx) | 
 |   63 »       »       »       So(ds.MakeKey("Hello", "world").Namespace(), ShouldEqual
     , "wat") | 
 |   64 »       »       }) | 
|   47  |   65  | 
|   48                 Convey("Can Put/Get", func() { |   66                 Convey("Can Put/Get", func() { | 
|   49                         orig := TestStruct{ |   67                         orig := TestStruct{ | 
|   50                                 ValueI: []int64{1, 7, 946688461000000, 996688461
     000000}, |   68                                 ValueI: []int64{1, 7, 946688461000000, 996688461
     000000}, | 
|   51                                 ValueB: []bool{true, false}, |   69                                 ValueB: []bool{true, false}, | 
|   52                                 ValueS: []string{"hello", "world"}, |   70                                 ValueS: []string{"hello", "world"}, | 
|   53                                 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
     96688461000000.0}, |   71                                 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
     96688461000000.0}, | 
|   54                                 ValueBS: [][]byte{ |   72                                 ValueBS: [][]byte{ | 
|   55                                         []byte("allo"), |   73                                         []byte("allo"), | 
|   56                                         []byte("hello"), |   74                                         []byte("hello"), | 
|   57                                         []byte("world"), |   75                                         []byte("world"), | 
|   58                                         []byte("zurple"), |   76                                         []byte("zurple"), | 
|   59                                 }, |   77                                 }, | 
|   60 »       »       »       »       ValueK: []*dstore.Key{ |   78 »       »       »       »       ValueK: []*datastore.Key{ | 
|   61                                         ds.NewKey("Something", "Cool", 0, nil), |   79                                         ds.NewKey("Something", "Cool", 0, nil), | 
|   62                                         ds.NewKey("Something", "", 1, nil), |   80                                         ds.NewKey("Something", "", 1, nil), | 
|   63                                         ds.NewKey("Something", "Recursive", 0, |   81                                         ds.NewKey("Something", "Recursive", 0, | 
|   64                                                 ds.NewKey("Parent", "", 2, nil))
     , |   82                                                 ds.NewKey("Parent", "", 2, nil))
     , | 
|   65                                 }, |   83                                 }, | 
|   66                                 ValueBK: []blobstore.Key{"bellow", "hello"}, |   84                                 ValueBK: []blobstore.Key{"bellow", "hello"}, | 
|   67 »       »       »       »       ValueGP: []dstore.GeoPoint{ |   85 »       »       »       »       ValueGP: []datastore.GeoPoint{ | 
|   68                                         {Lat: 120.7, Lng: 95.5}, |   86                                         {Lat: 120.7, Lng: 95.5}, | 
|   69                                 }, |   87                                 }, | 
|   70                         } |   88                         } | 
|   71                         So(ds.Put(&orig), ShouldBeNil) |   89                         So(ds.Put(&orig), ShouldBeNil) | 
|   72  |   90  | 
|   73                         ret := TestStruct{ID: orig.ID} |   91                         ret := TestStruct{ID: orig.ID} | 
|   74                         So(ds.Get(&ret), ShouldBeNil) |   92                         So(ds.Get(&ret), ShouldBeNil) | 
|   75                         So(ret, ShouldResemble, orig) |   93                         So(ret, ShouldResemble, orig) | 
|   76  |   94  | 
|   77                         // can't be sure the indexes have caught up... so sleep |   95                         // can't be sure the indexes have caught up... so sleep | 
|   78                         time.Sleep(time.Second) |   96                         time.Sleep(time.Second) | 
|   79  |   97  | 
|   80                         Convey("Can query", func() { |   98                         Convey("Can query", func() { | 
|   81 »       »       »       »       q := dstore.NewQuery("TestStruct") |   99 »       »       »       »       q := datastore.NewQuery("TestStruct") | 
|   82 »       »       »       »       ds.Run(q, func(ts *TestStruct, _ dstore.CursorCB
     ) bool { |  100 »       »       »       »       ds.Run(q, func(ts *TestStruct, _ datastore.Curso
     rCB) bool { | 
|   83                                         So(*ts, ShouldResemble, orig) |  101                                         So(*ts, ShouldResemble, orig) | 
|   84                                         return true |  102                                         return true | 
|   85                                 }) |  103                                 }) | 
|   86                                 count, err := ds.Count(q) |  104                                 count, err := ds.Count(q) | 
|   87                                 So(err, ShouldBeNil) |  105                                 So(err, ShouldBeNil) | 
|   88                                 So(count, ShouldEqual, 1) |  106                                 So(count, ShouldEqual, 1) | 
|   89                         }) |  107                         }) | 
|   90  |  108  | 
|   91                         Convey("Can project", func() { |  109                         Convey("Can project", func() { | 
|   92 »       »       »       »       q := dstore.NewQuery("TestStruct").Project("Valu
     eS") |  110 »       »       »       »       q := datastore.NewQuery("TestStruct").Project("V
     alueS") | 
|   93 »       »       »       »       rslts := []dstore.PropertyMap{} |  111 »       »       »       »       rslts := []datastore.PropertyMap{} | 
|   94                                 So(ds.GetAll(q, &rslts), ShouldBeNil) |  112                                 So(ds.GetAll(q, &rslts), ShouldBeNil) | 
|   95 »       »       »       »       So(rslts, ShouldResemble, []dstore.PropertyMap{ |  113 »       »       »       »       So(rslts, ShouldResemble, []datastore.PropertyMa
     p{ | 
|   96                                         { |  114                                         { | 
|   97                                                 "$key":   {mpNI(ds.KeyForObj(&or
     ig))}, |  115                                                 "$key":   {mpNI(ds.KeyForObj(&or
     ig))}, | 
|   98                                                 "ValueS": {mp("hello")}, |  116                                                 "ValueS": {mp("hello")}, | 
|   99                                         }, |  117                                         }, | 
|  100                                         { |  118                                         { | 
|  101                                                 "$key":   {mpNI(ds.KeyForObj(&or
     ig))}, |  119                                                 "$key":   {mpNI(ds.KeyForObj(&or
     ig))}, | 
|  102                                                 "ValueS": {mp("world")}, |  120                                                 "ValueS": {mp("world")}, | 
|  103                                         }, |  121                                         }, | 
|  104                                 }) |  122                                 }) | 
|  105  |  123  | 
|  106 »       »       »       »       q = dstore.NewQuery("TestStruct").Project("Value
     BS") |  124 »       »       »       »       q = datastore.NewQuery("TestStruct").Project("Va
     lueBS") | 
|  107 »       »       »       »       rslts = []dstore.PropertyMap{} |  125 »       »       »       »       rslts = []datastore.PropertyMap{} | 
|  108                                 So(ds.GetAll(q, &rslts), ShouldBeNil) |  126                                 So(ds.GetAll(q, &rslts), ShouldBeNil) | 
|  109 »       »       »       »       So(rslts, ShouldResemble, []dstore.PropertyMap{ |  127 »       »       »       »       So(rslts, ShouldResemble, []datastore.PropertyMa
     p{ | 
|  110                                         { |  128                                         { | 
|  111                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, |  129                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, | 
|  112                                                 "ValueBS": {mp("allo")}, |  130                                                 "ValueBS": {mp("allo")}, | 
|  113                                         }, |  131                                         }, | 
|  114                                         { |  132                                         { | 
|  115                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, |  133                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, | 
|  116                                                 "ValueBS": {mp("hello")}, |  134                                                 "ValueBS": {mp("hello")}, | 
|  117                                         }, |  135                                         }, | 
|  118                                         { |  136                                         { | 
|  119                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, |  137                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, | 
|  120                                                 "ValueBS": {mp("world")}, |  138                                                 "ValueBS": {mp("world")}, | 
|  121                                         }, |  139                                         }, | 
|  122                                         { |  140                                         { | 
|  123                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, |  141                                                 "$key":    {mpNI(ds.KeyForObj(&o
     rig))}, | 
|  124                                                 "ValueBS": {mp("zurple")}, |  142                                                 "ValueBS": {mp("zurple")}, | 
|  125                                         }, |  143                                         }, | 
|  126                                 }) |  144                                 }) | 
|  127  |  145  | 
|  128                                 count, err := ds.Count(q) |  146                                 count, err := ds.Count(q) | 
|  129                                 So(err, ShouldBeNil) |  147                                 So(err, ShouldBeNil) | 
|  130                                 So(count, ShouldEqual, 4) |  148                                 So(count, ShouldEqual, 4) | 
|  131                         }) |  149                         }) | 
|  132                 }) |  150                 }) | 
|  133  |  151  | 
|  134                 Convey("Can Put/Get (time)", func() { |  152                 Convey("Can Put/Get (time)", func() { | 
|  135                         // time comparisons in Go are wonky, so this is pulled o
     ut |  153                         // time comparisons in Go are wonky, so this is pulled o
     ut | 
|  136 »       »       »       pm := dstore.PropertyMap{ |  154 »       »       »       pm := datastore.PropertyMap{ | 
|  137                                 "$key": {mpNI(ds.NewKey("Something", "value", 0,
      nil))}, |  155                                 "$key": {mpNI(ds.NewKey("Something", "value", 0,
      nil))}, | 
|  138                                 "Time": { |  156                                 "Time": { | 
|  139                                         mp(time.Date(1938, time.January, 1, 1, 1
     , 1, 1, time.UTC)), |  157                                         mp(time.Date(1938, time.January, 1, 1, 1
     , 1, 1, time.UTC)), | 
|  140                                         mp(time.Time{}), |  158                                         mp(time.Time{}), | 
|  141                                 }, |  159                                 }, | 
|  142                         } |  160                         } | 
|  143                         So(ds.Put(&pm), ShouldBeNil) |  161                         So(ds.Put(&pm), ShouldBeNil) | 
|  144  |  162  | 
|  145 »       »       »       rslt := dstore.PropertyMap{} |  163 »       »       »       rslt := datastore.PropertyMap{} | 
|  146                         rslt.SetMeta("key", ds.KeyForObj(pm)) |  164                         rslt.SetMeta("key", ds.KeyForObj(pm)) | 
|  147                         So(ds.Get(&rslt), ShouldBeNil) |  165                         So(ds.Get(&rslt), ShouldBeNil) | 
|  148  |  166  | 
|  149                         So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0
     ].Value()) |  167                         So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0
     ].Value()) | 
|  150  |  168  | 
|  151 »       »       »       q := dstore.NewQuery("Something").Project("Time") |  169 »       »       »       q := datastore.NewQuery("Something").Project("Time") | 
|  152 »       »       »       all := []dstore.PropertyMap{} |  170 »       »       »       all := []datastore.PropertyMap{} | 
|  153                         So(ds.GetAll(q, &all), ShouldBeNil) |  171                         So(ds.GetAll(q, &all), ShouldBeNil) | 
|  154                         So(len(all), ShouldEqual, 2) |  172                         So(len(all), ShouldEqual, 2) | 
|  155                         prop := all[0]["Time"][0] |  173                         prop := all[0]["Time"][0] | 
|  156 »       »       »       So(prop.Type(), ShouldEqual, dstore.PTInt) |  174 »       »       »       So(prop.Type(), ShouldEqual, datastore.PTInt) | 
|  157  |  175  | 
|  158 »       »       »       tval, err := prop.Project(dstore.PTTime) |  176 »       »       »       tval, err := prop.Project(datastore.PTTime) | 
|  159                         So(err, ShouldBeNil) |  177                         So(err, ShouldBeNil) | 
|  160                         So(tval, ShouldResemble, time.Time{}) |  178                         So(tval, ShouldResemble, time.Time{}) | 
|  161  |  179  | 
|  162 »       »       »       tval, err = all[1]["Time"][0].Project(dstore.PTTime) |  180 »       »       »       tval, err = all[1]["Time"][0].Project(datastore.PTTime) | 
|  163                         So(err, ShouldBeNil) |  181                         So(err, ShouldBeNil) | 
|  164                         So(tval, ShouldResemble, pm["Time"][0].Value()) |  182                         So(tval, ShouldResemble, pm["Time"][0].Value()) | 
|  165  |  183  | 
|  166 »       »       »       ent := dstore.PropertyMap{ |  184 »       »       »       ent := datastore.PropertyMap{ | 
|  167                                 "$key": {mpNI(ds.MakeKey("Something", "value"))}
     , |  185                                 "$key": {mpNI(ds.MakeKey("Something", "value"))}
     , | 
|  168                         } |  186                         } | 
|  169                         So(ds.Get(&ent), ShouldBeNil) |  187                         So(ds.Get(&ent), ShouldBeNil) | 
|  170                         So(ent["Time"], ShouldResemble, pm["Time"]) |  188                         So(ent["Time"], ShouldResemble, pm["Time"]) | 
|  171                 }) |  189                 }) | 
|  172         }) |  190         }) | 
|  173 } |  191 } | 
| OLD | NEW |