You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1278 lines
31 KiB

  1. // Copyright 2014 Google LLC
  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. package datastore
  15. import (
  16. "encoding/json"
  17. "errors"
  18. "flag"
  19. "fmt"
  20. "log"
  21. "net"
  22. "os"
  23. "reflect"
  24. "sort"
  25. "strings"
  26. "sync"
  27. "testing"
  28. "time"
  29. "cloud.google.com/go/internal/testutil"
  30. "cloud.google.com/go/rpcreplay"
  31. "golang.org/x/net/context"
  32. "google.golang.org/api/iterator"
  33. "google.golang.org/api/option"
  34. "google.golang.org/grpc"
  35. "google.golang.org/grpc/codes"
  36. "google.golang.org/grpc/status"
  37. )
  38. // TODO(djd): Make test entity clean up more robust: some test entities may
  39. // be left behind if tests are aborted, the transport fails, etc.
  40. var timeNow = time.Now()
  41. // suffix is a timestamp-based suffix which is appended to key names,
  42. // particularly for the root keys of entity groups. This reduces flakiness
  43. // when the tests are run in parallel.
  44. var suffix string
  45. const replayFilename = "datastore.replay"
  46. type replayInfo struct {
  47. ProjectID string
  48. Time time.Time
  49. }
  50. var (
  51. record = flag.Bool("record", false, "record RPCs")
  52. newTestClient = func(ctx context.Context, t *testing.T) *Client {
  53. return newClient(ctx, t, nil)
  54. }
  55. )
  56. func TestMain(m *testing.M) {
  57. os.Exit(testMain(m))
  58. }
  59. func testMain(m *testing.M) int {
  60. flag.Parse()
  61. if testing.Short() {
  62. if *record {
  63. log.Fatal("cannot combine -short and -record")
  64. }
  65. if _, err := os.Stat(replayFilename); err == nil {
  66. initReplay()
  67. }
  68. } else if *record {
  69. if testutil.ProjID() == "" {
  70. log.Fatal("must record with a project ID")
  71. }
  72. b, err := json.Marshal(replayInfo{
  73. ProjectID: testutil.ProjID(),
  74. Time: timeNow,
  75. })
  76. if err != nil {
  77. log.Fatal(err)
  78. }
  79. rec, err := rpcreplay.NewRecorder(replayFilename, b)
  80. if err != nil {
  81. log.Fatal(err)
  82. }
  83. defer func() {
  84. if err := rec.Close(); err != nil {
  85. log.Fatalf("closing recorder: %v", err)
  86. }
  87. }()
  88. newTestClient = func(ctx context.Context, t *testing.T) *Client {
  89. return newClient(ctx, t, rec.DialOptions())
  90. }
  91. log.Printf("recording to %s", replayFilename)
  92. }
  93. suffix = fmt.Sprintf("-t%d", timeNow.UnixNano())
  94. return m.Run()
  95. }
  96. func initReplay() {
  97. rep, err := rpcreplay.NewReplayer(replayFilename)
  98. if err != nil {
  99. log.Fatal(err)
  100. }
  101. defer rep.Close()
  102. var ri replayInfo
  103. if err := json.Unmarshal(rep.Initial(), &ri); err != nil {
  104. log.Fatalf("unmarshaling initial replay info: %v", err)
  105. }
  106. timeNow = ri.Time.In(time.Local)
  107. conn, err := replayConn(rep)
  108. if err != nil {
  109. log.Fatal(err)
  110. }
  111. newTestClient = func(ctx context.Context, t *testing.T) *Client {
  112. client, err := NewClient(ctx, ri.ProjectID, option.WithGRPCConn(conn))
  113. if err != nil {
  114. t.Fatalf("NewClient: %v", err)
  115. }
  116. return client
  117. }
  118. log.Printf("replaying from %s", replayFilename)
  119. }
  120. func replayConn(rep *rpcreplay.Replayer) (*grpc.ClientConn, error) {
  121. // If we make a real connection we need creds from somewhere, and they
  122. // might not be available, for instance on Travis.
  123. // Replaying doesn't require a connection live at all, but we need
  124. // something to attach gRPC interceptors to.
  125. // So we start a local listener and connect to it, then close them down.
  126. // TODO(jba): build something like this into the replayer?
  127. l, err := net.Listen("tcp", "127.0.0.1:0")
  128. if err != nil {
  129. return nil, err
  130. }
  131. conn, err := grpc.Dial(l.Addr().String(),
  132. append([]grpc.DialOption{grpc.WithInsecure()}, rep.DialOptions()...)...)
  133. if err != nil {
  134. return nil, err
  135. }
  136. conn.Close()
  137. l.Close()
  138. return conn, nil
  139. }
  140. func newClient(ctx context.Context, t *testing.T, dialOpts []grpc.DialOption) *Client {
  141. if testing.Short() {
  142. t.Skip("Integration tests skipped in short mode")
  143. }
  144. ts := testutil.TokenSource(ctx, ScopeDatastore)
  145. if ts == nil {
  146. t.Skip("Integration tests skipped. See CONTRIBUTING.md for details")
  147. }
  148. opts := []option.ClientOption{option.WithTokenSource(ts)}
  149. for _, opt := range dialOpts {
  150. opts = append(opts, option.WithGRPCDialOption(opt))
  151. }
  152. client, err := NewClient(ctx, testutil.ProjID(), opts...)
  153. if err != nil {
  154. t.Fatalf("NewClient: %v", err)
  155. }
  156. return client
  157. }
  158. func TestBasics(t *testing.T) {
  159. ctx, _ := context.WithTimeout(context.Background(), time.Second*20)
  160. client := newTestClient(ctx, t)
  161. defer client.Close()
  162. type X struct {
  163. I int
  164. S string
  165. T time.Time
  166. }
  167. x0 := X{66, "99", timeNow.Truncate(time.Millisecond)}
  168. k, err := client.Put(ctx, IncompleteKey("BasicsX", nil), &x0)
  169. if err != nil {
  170. t.Fatalf("client.Put: %v", err)
  171. }
  172. x1 := X{}
  173. err = client.Get(ctx, k, &x1)
  174. if err != nil {
  175. t.Errorf("client.Get: %v", err)
  176. }
  177. err = client.Delete(ctx, k)
  178. if err != nil {
  179. t.Errorf("client.Delete: %v", err)
  180. }
  181. if !testutil.Equal(x0, x1) {
  182. t.Errorf("compare: x0=%v, x1=%v", x0, x1)
  183. }
  184. }
  185. func TestTopLevelKeyLoaded(t *testing.T) {
  186. ctx, _ := context.WithTimeout(context.Background(), time.Second*20)
  187. client := newTestClient(ctx, t)
  188. defer client.Close()
  189. completeKey := NameKey("EntityWithKey", "myent", nil)
  190. type EntityWithKey struct {
  191. I int
  192. S string
  193. K *Key `datastore:"__key__"`
  194. }
  195. in := &EntityWithKey{
  196. I: 12,
  197. S: "abcd",
  198. }
  199. k, err := client.Put(ctx, completeKey, in)
  200. if err != nil {
  201. t.Fatalf("client.Put: %v", err)
  202. }
  203. var e EntityWithKey
  204. err = client.Get(ctx, k, &e)
  205. if err != nil {
  206. t.Fatalf("client.Get: %v", err)
  207. }
  208. // The two keys should be absolutely identical.
  209. if !testutil.Equal(e.K, k) {
  210. t.Fatalf("e.K not equal to k; got %#v, want %#v", e.K, k)
  211. }
  212. }
  213. func TestListValues(t *testing.T) {
  214. ctx := context.Background()
  215. client := newTestClient(ctx, t)
  216. defer client.Close()
  217. p0 := PropertyList{
  218. {Name: "L", Value: []interface{}{int64(12), "string", true}},
  219. }
  220. k, err := client.Put(ctx, IncompleteKey("ListValue", nil), &p0)
  221. if err != nil {
  222. t.Fatalf("client.Put: %v", err)
  223. }
  224. var p1 PropertyList
  225. if err := client.Get(ctx, k, &p1); err != nil {
  226. t.Errorf("client.Get: %v", err)
  227. }
  228. if !testutil.Equal(p0, p1) {
  229. t.Errorf("compare:\np0=%v\np1=%#v", p0, p1)
  230. }
  231. if err = client.Delete(ctx, k); err != nil {
  232. t.Errorf("client.Delete: %v", err)
  233. }
  234. }
  235. func TestGetMulti(t *testing.T) {
  236. ctx := context.Background()
  237. client := newTestClient(ctx, t)
  238. defer client.Close()
  239. type X struct {
  240. I int
  241. }
  242. p := NameKey("X", "x"+suffix, nil)
  243. cases := []struct {
  244. key *Key
  245. put bool
  246. }{
  247. {key: NameKey("X", "item1", p), put: true},
  248. {key: NameKey("X", "item2", p), put: false},
  249. {key: NameKey("X", "item3", p), put: false},
  250. {key: NameKey("X", "item3", p), put: false},
  251. {key: NameKey("X", "item4", p), put: true},
  252. }
  253. var src, dst []*X
  254. var srcKeys, dstKeys []*Key
  255. for _, c := range cases {
  256. dst = append(dst, &X{})
  257. dstKeys = append(dstKeys, c.key)
  258. if c.put {
  259. src = append(src, &X{})
  260. srcKeys = append(srcKeys, c.key)
  261. }
  262. }
  263. if _, err := client.PutMulti(ctx, srcKeys, src); err != nil {
  264. t.Error(err)
  265. }
  266. err := client.GetMulti(ctx, dstKeys, dst)
  267. if err == nil {
  268. t.Errorf("client.GetMulti got %v, expected error", err)
  269. }
  270. e, ok := err.(MultiError)
  271. if !ok {
  272. t.Errorf("client.GetMulti got %T, expected MultiError", err)
  273. }
  274. for i, err := range e {
  275. got, want := err, (error)(nil)
  276. if !cases[i].put {
  277. got, want = err, ErrNoSuchEntity
  278. }
  279. if got != want {
  280. t.Errorf("MultiError[%d] == %v, want %v", i, got, want)
  281. }
  282. }
  283. }
  284. type Z struct {
  285. S string
  286. T string `datastore:",noindex"`
  287. P []byte
  288. K []byte `datastore:",noindex"`
  289. }
  290. func (z Z) String() string {
  291. var lens []string
  292. v := reflect.ValueOf(z)
  293. for i := 0; i < v.NumField(); i++ {
  294. if l := v.Field(i).Len(); l > 0 {
  295. lens = append(lens, fmt.Sprintf("len(%s)=%d", v.Type().Field(i).Name, l))
  296. }
  297. }
  298. return fmt.Sprintf("Z{ %s }", strings.Join(lens, ","))
  299. }
  300. func TestUnindexableValues(t *testing.T) {
  301. ctx := context.Background()
  302. client := newTestClient(ctx, t)
  303. defer client.Close()
  304. x1500 := strings.Repeat("x", 1500)
  305. x1501 := strings.Repeat("x", 1501)
  306. testCases := []struct {
  307. in Z
  308. wantErr bool
  309. }{
  310. {in: Z{S: x1500}, wantErr: false},
  311. {in: Z{S: x1501}, wantErr: true},
  312. {in: Z{T: x1500}, wantErr: false},
  313. {in: Z{T: x1501}, wantErr: false},
  314. {in: Z{P: []byte(x1500)}, wantErr: false},
  315. {in: Z{P: []byte(x1501)}, wantErr: true},
  316. {in: Z{K: []byte(x1500)}, wantErr: false},
  317. {in: Z{K: []byte(x1501)}, wantErr: false},
  318. }
  319. for _, tt := range testCases {
  320. _, err := client.Put(ctx, IncompleteKey("BasicsZ", nil), &tt.in)
  321. if (err != nil) != tt.wantErr {
  322. t.Errorf("client.Put %s got err %v, want err %t", tt.in, err, tt.wantErr)
  323. }
  324. }
  325. }
  326. func TestNilKey(t *testing.T) {
  327. ctx := context.Background()
  328. client := newTestClient(ctx, t)
  329. defer client.Close()
  330. testCases := []struct {
  331. in K0
  332. wantErr bool
  333. }{
  334. {in: K0{K: testKey0}, wantErr: false},
  335. {in: K0{}, wantErr: false},
  336. }
  337. for _, tt := range testCases {
  338. _, err := client.Put(ctx, IncompleteKey("NilKey", nil), &tt.in)
  339. if (err != nil) != tt.wantErr {
  340. t.Errorf("client.Put %s got err %v, want err %t", tt.in, err, tt.wantErr)
  341. }
  342. }
  343. }
  344. type SQChild struct {
  345. I, J int
  346. T, U int64
  347. }
  348. type SQTestCase struct {
  349. desc string
  350. q *Query
  351. wantCount int
  352. wantSum int
  353. }
  354. func testSmallQueries(t *testing.T, ctx context.Context, client *Client, parent *Key, children []*SQChild,
  355. testCases []SQTestCase, extraTests ...func()) {
  356. keys := make([]*Key, len(children))
  357. for i := range keys {
  358. keys[i] = IncompleteKey("SQChild", parent)
  359. }
  360. keys, err := client.PutMulti(ctx, keys, children)
  361. if err != nil {
  362. t.Fatalf("client.PutMulti: %v", err)
  363. }
  364. defer func() {
  365. err := client.DeleteMulti(ctx, keys)
  366. if err != nil {
  367. t.Errorf("client.DeleteMulti: %v", err)
  368. }
  369. }()
  370. for _, tc := range testCases {
  371. count, err := client.Count(ctx, tc.q)
  372. if err != nil {
  373. t.Errorf("Count %q: %v", tc.desc, err)
  374. continue
  375. }
  376. if count != tc.wantCount {
  377. t.Errorf("Count %q: got %d want %d", tc.desc, count, tc.wantCount)
  378. continue
  379. }
  380. }
  381. for _, tc := range testCases {
  382. var got []SQChild
  383. _, err := client.GetAll(ctx, tc.q, &got)
  384. if err != nil {
  385. t.Errorf("client.GetAll %q: %v", tc.desc, err)
  386. continue
  387. }
  388. sum := 0
  389. for _, c := range got {
  390. sum += c.I + c.J
  391. }
  392. if sum != tc.wantSum {
  393. t.Errorf("sum %q: got %d want %d", tc.desc, sum, tc.wantSum)
  394. continue
  395. }
  396. }
  397. for _, x := range extraTests {
  398. x()
  399. }
  400. }
  401. func TestFilters(t *testing.T) {
  402. ctx := context.Background()
  403. client := newTestClient(ctx, t)
  404. defer client.Close()
  405. parent := NameKey("SQParent", "TestFilters"+suffix, nil)
  406. now := timeNow.Truncate(time.Millisecond).Unix()
  407. children := []*SQChild{
  408. {I: 0, T: now, U: now},
  409. {I: 1, T: now, U: now},
  410. {I: 2, T: now, U: now},
  411. {I: 3, T: now, U: now},
  412. {I: 4, T: now, U: now},
  413. {I: 5, T: now, U: now},
  414. {I: 6, T: now, U: now},
  415. {I: 7, T: now, U: now},
  416. }
  417. baseQuery := NewQuery("SQChild").Ancestor(parent).Filter("T=", now)
  418. testSmallQueries(t, ctx, client, parent, children, []SQTestCase{
  419. {
  420. "I>1",
  421. baseQuery.Filter("I>", 1),
  422. 6,
  423. 2 + 3 + 4 + 5 + 6 + 7,
  424. },
  425. {
  426. "I>2 AND I<=5",
  427. baseQuery.Filter("I>", 2).Filter("I<=", 5),
  428. 3,
  429. 3 + 4 + 5,
  430. },
  431. {
  432. "I>=3 AND I<3",
  433. baseQuery.Filter("I>=", 3).Filter("I<", 3),
  434. 0,
  435. 0,
  436. },
  437. {
  438. "I=4",
  439. baseQuery.Filter("I=", 4),
  440. 1,
  441. 4,
  442. },
  443. }, func() {
  444. got := []*SQChild{}
  445. want := []*SQChild{
  446. {I: 0, T: now, U: now},
  447. {I: 1, T: now, U: now},
  448. {I: 2, T: now, U: now},
  449. {I: 3, T: now, U: now},
  450. {I: 4, T: now, U: now},
  451. {I: 5, T: now, U: now},
  452. {I: 6, T: now, U: now},
  453. {I: 7, T: now, U: now},
  454. }
  455. _, err := client.GetAll(ctx, baseQuery.Order("I"), &got)
  456. if err != nil {
  457. t.Errorf("client.GetAll: %v", err)
  458. }
  459. if !testutil.Equal(got, want) {
  460. t.Errorf("compare: got=%v, want=%v", got, want)
  461. }
  462. }, func() {
  463. got := []*SQChild{}
  464. want := []*SQChild{
  465. {I: 7, T: now, U: now},
  466. {I: 6, T: now, U: now},
  467. {I: 5, T: now, U: now},
  468. {I: 4, T: now, U: now},
  469. {I: 3, T: now, U: now},
  470. {I: 2, T: now, U: now},
  471. {I: 1, T: now, U: now},
  472. {I: 0, T: now, U: now},
  473. }
  474. _, err := client.GetAll(ctx, baseQuery.Order("-I"), &got)
  475. if err != nil {
  476. t.Errorf("client.GetAll: %v", err)
  477. }
  478. if !testutil.Equal(got, want) {
  479. t.Errorf("compare: got=%v, want=%v", got, want)
  480. }
  481. })
  482. }
  483. type ckey struct{}
  484. func TestLargeQuery(t *testing.T) {
  485. ctx := context.Background()
  486. client := newTestClient(ctx, t)
  487. defer client.Close()
  488. parent := NameKey("LQParent", "TestFilters"+suffix, nil)
  489. now := timeNow.Truncate(time.Millisecond).Unix()
  490. // Make a large number of children entities.
  491. const n = 800
  492. children := make([]*SQChild, 0, n)
  493. keys := make([]*Key, 0, n)
  494. for i := 0; i < n; i++ {
  495. children = append(children, &SQChild{I: i, T: now, U: now})
  496. keys = append(keys, IncompleteKey("SQChild", parent))
  497. }
  498. // Store using PutMulti in batches.
  499. const batchSize = 500
  500. for i := 0; i < n; i = i + 500 {
  501. j := i + batchSize
  502. if j > n {
  503. j = n
  504. }
  505. fullKeys, err := client.PutMulti(ctx, keys[i:j], children[i:j])
  506. if err != nil {
  507. t.Fatalf("PutMulti(%d, %d): %v", i, j, err)
  508. }
  509. defer func() {
  510. err := client.DeleteMulti(ctx, fullKeys)
  511. if err != nil {
  512. t.Errorf("client.DeleteMulti: %v", err)
  513. }
  514. }()
  515. }
  516. q := NewQuery("SQChild").Ancestor(parent).Filter("T=", now).Order("I")
  517. // Wait group to allow us to run query tests in parallel below.
  518. var wg sync.WaitGroup
  519. // Check we get the expected count and results for various limits/offsets.
  520. queryTests := []struct {
  521. limit, offset, want int
  522. }{
  523. // Just limit.
  524. {limit: 0, want: 0},
  525. {limit: 100, want: 100},
  526. {limit: 501, want: 501},
  527. {limit: n, want: n},
  528. {limit: n * 2, want: n},
  529. {limit: -1, want: n},
  530. // Just offset.
  531. {limit: -1, offset: 100, want: n - 100},
  532. {limit: -1, offset: 500, want: n - 500},
  533. {limit: -1, offset: n, want: 0},
  534. // Limit and offset.
  535. {limit: 100, offset: 100, want: 100},
  536. {limit: 1000, offset: 100, want: n - 100},
  537. {limit: 500, offset: 500, want: n - 500},
  538. }
  539. for _, tt := range queryTests {
  540. q := q.Limit(tt.limit).Offset(tt.offset)
  541. wg.Add(1)
  542. go func(limit, offset, want int) {
  543. defer wg.Done()
  544. // Check Count returns the expected number of results.
  545. count, err := client.Count(ctx, q)
  546. if err != nil {
  547. t.Errorf("client.Count(limit=%d offset=%d): %v", limit, offset, err)
  548. return
  549. }
  550. if count != want {
  551. t.Errorf("Count(limit=%d offset=%d) returned %d, want %d", limit, offset, count, want)
  552. }
  553. var got []SQChild
  554. _, err = client.GetAll(ctx, q, &got)
  555. if err != nil {
  556. t.Errorf("client.GetAll(limit=%d offset=%d): %v", limit, offset, err)
  557. return
  558. }
  559. if len(got) != want {
  560. t.Errorf("GetAll(limit=%d offset=%d) returned %d, want %d", limit, offset, len(got), want)
  561. }
  562. for i, child := range got {
  563. if got, want := child.I, i+offset; got != want {
  564. t.Errorf("GetAll(limit=%d offset=%d) got[%d].I == %d; want %d", limit, offset, i, got, want)
  565. break
  566. }
  567. }
  568. }(tt.limit, tt.offset, tt.want)
  569. }
  570. // Also check iterator cursor behaviour.
  571. cursorTests := []struct {
  572. limit, offset int // Query limit and offset.
  573. count int // The number of times to call "next"
  574. want int // The I value of the desired element, -1 for "Done".
  575. }{
  576. // No limits.
  577. {count: 0, limit: -1, want: 0},
  578. {count: 5, limit: -1, want: 5},
  579. {count: 500, limit: -1, want: 500},
  580. {count: 1000, limit: -1, want: -1}, // No more results.
  581. // Limits.
  582. {count: 5, limit: 5, want: 5},
  583. {count: 500, limit: 5, want: 5},
  584. {count: 1000, limit: 1000, want: -1}, // No more results.
  585. // Offsets.
  586. {count: 0, offset: 5, limit: -1, want: 5},
  587. {count: 5, offset: 5, limit: -1, want: 10},
  588. {count: 200, offset: 500, limit: -1, want: 700},
  589. {count: 200, offset: 1000, limit: -1, want: -1}, // No more results.
  590. }
  591. for _, tt := range cursorTests {
  592. wg.Add(1)
  593. go func(count, limit, offset, want int) {
  594. defer wg.Done()
  595. ctx := context.WithValue(ctx, ckey{}, fmt.Sprintf("c=%d,l=%d,o=%d", count, limit, offset))
  596. // Run iterator through count calls to Next.
  597. it := client.Run(ctx, q.Limit(limit).Offset(offset).KeysOnly())
  598. for i := 0; i < count; i++ {
  599. _, err := it.Next(nil)
  600. if err == iterator.Done {
  601. break
  602. }
  603. if err != nil {
  604. t.Errorf("count=%d, limit=%d, offset=%d: it.Next failed at i=%d", count, limit, offset, i)
  605. return
  606. }
  607. }
  608. // Grab the cursor.
  609. cursor, err := it.Cursor()
  610. if err != nil {
  611. t.Errorf("count=%d, limit=%d, offset=%d: it.Cursor: %v", count, limit, offset, err)
  612. return
  613. }
  614. // Make a request for the next element.
  615. it = client.Run(ctx, q.Limit(1).Start(cursor))
  616. var entity SQChild
  617. _, err = it.Next(&entity)
  618. switch {
  619. case want == -1:
  620. if err != iterator.Done {
  621. t.Errorf("count=%d, limit=%d, offset=%d: it.Next from cursor %v, want Done", count, limit, offset, err)
  622. }
  623. case err != nil:
  624. t.Errorf("count=%d, limit=%d, offset=%d: it.Next from cursor: %v, want nil", count, limit, offset, err)
  625. case entity.I != want:
  626. t.Errorf("count=%d, limit=%d, offset=%d: got.I = %d, want %d", count, limit, offset, entity.I, want)
  627. }
  628. }(tt.count, tt.limit, tt.offset, tt.want)
  629. }
  630. wg.Wait()
  631. }
  632. func TestEventualConsistency(t *testing.T) {
  633. // TODO(jba): either make this actually test eventual consistency, or
  634. // delete it. Currently it behaves the same with or without the
  635. // EventualConsistency call.
  636. ctx := context.Background()
  637. client := newTestClient(ctx, t)
  638. defer client.Close()
  639. parent := NameKey("SQParent", "TestEventualConsistency"+suffix, nil)
  640. now := timeNow.Truncate(time.Millisecond).Unix()
  641. children := []*SQChild{
  642. {I: 0, T: now, U: now},
  643. {I: 1, T: now, U: now},
  644. {I: 2, T: now, U: now},
  645. }
  646. query := NewQuery("SQChild").Ancestor(parent).Filter("T =", now).EventualConsistency()
  647. testSmallQueries(t, ctx, client, parent, children, nil, func() {
  648. got, err := client.Count(ctx, query)
  649. if err != nil {
  650. t.Fatalf("Count: %v", err)
  651. }
  652. if got < 0 || 3 < got {
  653. t.Errorf("Count: got %d, want [0,3]", got)
  654. }
  655. })
  656. }
  657. func TestProjection(t *testing.T) {
  658. ctx := context.Background()
  659. client := newTestClient(ctx, t)
  660. defer client.Close()
  661. parent := NameKey("SQParent", "TestProjection"+suffix, nil)
  662. now := timeNow.Truncate(time.Millisecond).Unix()
  663. children := []*SQChild{
  664. {I: 1 << 0, J: 100, T: now, U: now},
  665. {I: 1 << 1, J: 100, T: now, U: now},
  666. {I: 1 << 2, J: 200, T: now, U: now},
  667. {I: 1 << 3, J: 300, T: now, U: now},
  668. {I: 1 << 4, J: 300, T: now, U: now},
  669. }
  670. baseQuery := NewQuery("SQChild").Ancestor(parent).Filter("T=", now).Filter("J>", 150)
  671. testSmallQueries(t, ctx, client, parent, children, []SQTestCase{
  672. {
  673. "project",
  674. baseQuery.Project("J"),
  675. 3,
  676. 200 + 300 + 300,
  677. },
  678. {
  679. "distinct",
  680. baseQuery.Project("J").Distinct(),
  681. 2,
  682. 200 + 300,
  683. },
  684. {
  685. "distinct on",
  686. baseQuery.Project("J").DistinctOn("J"),
  687. 2,
  688. 200 + 300,
  689. },
  690. {
  691. "project on meaningful (GD_WHEN) field",
  692. baseQuery.Project("U"),
  693. 3,
  694. 0,
  695. },
  696. })
  697. }
  698. func TestAllocateIDs(t *testing.T) {
  699. ctx := context.Background()
  700. client := newTestClient(ctx, t)
  701. defer client.Close()
  702. keys := make([]*Key, 5)
  703. for i := range keys {
  704. keys[i] = IncompleteKey("AllocID", nil)
  705. }
  706. keys, err := client.AllocateIDs(ctx, keys)
  707. if err != nil {
  708. t.Errorf("AllocID #0 failed: %v", err)
  709. }
  710. if want := len(keys); want != 5 {
  711. t.Errorf("Expected to allocate 5 keys, %d keys are found", want)
  712. }
  713. for _, k := range keys {
  714. if k.Incomplete() {
  715. t.Errorf("Unexpeceted incomplete key found: %v", k)
  716. }
  717. }
  718. }
  719. func TestGetAllWithFieldMismatch(t *testing.T) {
  720. ctx := context.Background()
  721. client := newTestClient(ctx, t)
  722. defer client.Close()
  723. type Fat struct {
  724. X, Y int
  725. }
  726. type Thin struct {
  727. X int
  728. }
  729. // Ancestor queries (those within an entity group) are strongly consistent
  730. // by default, which prevents a test from being flaky.
  731. // See https://cloud.google.com/appengine/docs/go/datastore/queries#Go_Data_consistency
  732. // for more information.
  733. parent := NameKey("SQParent", "TestGetAllWithFieldMismatch"+suffix, nil)
  734. putKeys := make([]*Key, 3)
  735. for i := range putKeys {
  736. putKeys[i] = IDKey("GetAllThing", int64(10+i), parent)
  737. _, err := client.Put(ctx, putKeys[i], &Fat{X: 20 + i, Y: 30 + i})
  738. if err != nil {
  739. t.Fatalf("client.Put: %v", err)
  740. }
  741. }
  742. var got []Thin
  743. want := []Thin{
  744. {X: 20},
  745. {X: 21},
  746. {X: 22},
  747. }
  748. getKeys, err := client.GetAll(ctx, NewQuery("GetAllThing").Ancestor(parent), &got)
  749. if len(getKeys) != 3 && !testutil.Equal(getKeys, putKeys) {
  750. t.Errorf("client.GetAll: keys differ\ngetKeys=%v\nputKeys=%v", getKeys, putKeys)
  751. }
  752. if !testutil.Equal(got, want) {
  753. t.Errorf("client.GetAll: entities differ\ngot =%v\nwant=%v", got, want)
  754. }
  755. if _, ok := err.(*ErrFieldMismatch); !ok {
  756. t.Errorf("client.GetAll: got err=%v, want ErrFieldMismatch", err)
  757. }
  758. }
  759. func TestKindlessQueries(t *testing.T) {
  760. ctx := context.Background()
  761. client := newTestClient(ctx, t)
  762. defer client.Close()
  763. type Dee struct {
  764. I int
  765. Why string
  766. }
  767. type Dum struct {
  768. I int
  769. Pling string
  770. }
  771. parent := NameKey("Tweedle", "tweedle"+suffix, nil)
  772. keys := []*Key{
  773. NameKey("Dee", "dee0", parent),
  774. NameKey("Dum", "dum1", parent),
  775. NameKey("Dum", "dum2", parent),
  776. NameKey("Dum", "dum3", parent),
  777. }
  778. src := []interface{}{
  779. &Dee{1, "binary0001"},
  780. &Dum{2, "binary0010"},
  781. &Dum{4, "binary0100"},
  782. &Dum{8, "binary1000"},
  783. }
  784. keys, err := client.PutMulti(ctx, keys, src)
  785. if err != nil {
  786. t.Fatalf("put: %v", err)
  787. }
  788. testCases := []struct {
  789. desc string
  790. query *Query
  791. want []int
  792. wantErr string
  793. }{
  794. {
  795. desc: "Dee",
  796. query: NewQuery("Dee"),
  797. want: []int{1},
  798. },
  799. {
  800. desc: "Doh",
  801. query: NewQuery("Doh"),
  802. want: nil},
  803. {
  804. desc: "Dum",
  805. query: NewQuery("Dum"),
  806. want: []int{2, 4, 8},
  807. },
  808. {
  809. desc: "",
  810. query: NewQuery(""),
  811. want: []int{1, 2, 4, 8},
  812. },
  813. {
  814. desc: "Kindless filter",
  815. query: NewQuery("").Filter("__key__ =", keys[2]),
  816. want: []int{4},
  817. },
  818. {
  819. desc: "Kindless order",
  820. query: NewQuery("").Order("__key__"),
  821. want: []int{1, 2, 4, 8},
  822. },
  823. {
  824. desc: "Kindless bad filter",
  825. query: NewQuery("").Filter("I =", 4),
  826. wantErr: "kind is required",
  827. },
  828. {
  829. desc: "Kindless bad order",
  830. query: NewQuery("").Order("-__key__"),
  831. wantErr: "kind is required for all orders except __key__ ascending",
  832. },
  833. }
  834. loop:
  835. for _, tc := range testCases {
  836. q := tc.query.Ancestor(parent)
  837. gotCount, err := client.Count(ctx, q)
  838. if err != nil {
  839. if tc.wantErr == "" || !strings.Contains(err.Error(), tc.wantErr) {
  840. t.Errorf("count %q: err %v, want err %q", tc.desc, err, tc.wantErr)
  841. }
  842. continue
  843. }
  844. if tc.wantErr != "" {
  845. t.Errorf("count %q: want err %q", tc.desc, tc.wantErr)
  846. continue
  847. }
  848. if gotCount != len(tc.want) {
  849. t.Errorf("count %q: got %d want %d", tc.desc, gotCount, len(tc.want))
  850. continue
  851. }
  852. var got []int
  853. for iter := client.Run(ctx, q); ; {
  854. var dst struct {
  855. I int
  856. Why, Pling string
  857. }
  858. _, err := iter.Next(&dst)
  859. if err == iterator.Done {
  860. break
  861. }
  862. if err != nil {
  863. t.Errorf("iter.Next %q: %v", tc.desc, err)
  864. continue loop
  865. }
  866. got = append(got, dst.I)
  867. }
  868. sort.Ints(got)
  869. if !testutil.Equal(got, tc.want) {
  870. t.Errorf("elems %q: got %+v want %+v", tc.desc, got, tc.want)
  871. continue
  872. }
  873. }
  874. }
  875. func TestTransaction(t *testing.T) {
  876. ctx := context.Background()
  877. client := newTestClient(ctx, t)
  878. defer client.Close()
  879. type Counter struct {
  880. N int
  881. T time.Time
  882. }
  883. bangErr := errors.New("bang")
  884. tests := []struct {
  885. desc string
  886. causeConflict []bool
  887. retErr []error
  888. want int
  889. wantErr error
  890. }{
  891. {
  892. desc: "3 attempts, no conflicts",
  893. causeConflict: []bool{false},
  894. retErr: []error{nil},
  895. want: 11,
  896. },
  897. {
  898. desc: "1 attempt, user error",
  899. causeConflict: []bool{false},
  900. retErr: []error{bangErr},
  901. wantErr: bangErr,
  902. },
  903. {
  904. desc: "2 attempts, 1 conflict",
  905. causeConflict: []bool{true, false},
  906. retErr: []error{nil, nil},
  907. want: 13, // Each conflict increments by 2.
  908. },
  909. {
  910. desc: "3 attempts, 3 conflicts",
  911. causeConflict: []bool{true, true, true},
  912. retErr: []error{nil, nil, nil},
  913. wantErr: ErrConcurrentTransaction,
  914. },
  915. }
  916. for i, tt := range tests {
  917. // Put a new counter.
  918. c := &Counter{N: 10, T: timeNow}
  919. key, err := client.Put(ctx, IncompleteKey("TransCounter", nil), c)
  920. if err != nil {
  921. t.Errorf("%s: client.Put: %v", tt.desc, err)
  922. continue
  923. }
  924. defer client.Delete(ctx, key)
  925. // Increment the counter in a transaction.
  926. // The test case can manually cause a conflict or return an
  927. // error at each attempt.
  928. var attempts int
  929. _, err = client.RunInTransaction(ctx, func(tx *Transaction) error {
  930. attempts++
  931. if attempts > len(tt.causeConflict) {
  932. return fmt.Errorf("too many attempts. Got %d, max %d", attempts, len(tt.causeConflict))
  933. }
  934. var c Counter
  935. if err := tx.Get(key, &c); err != nil {
  936. return err
  937. }
  938. c.N++
  939. if _, err := tx.Put(key, &c); err != nil {
  940. return err
  941. }
  942. if tt.causeConflict[attempts-1] {
  943. c.N += 1
  944. if _, err := client.Put(ctx, key, &c); err != nil {
  945. return err
  946. }
  947. }
  948. return tt.retErr[attempts-1]
  949. }, MaxAttempts(i))
  950. // Check the error returned by RunInTransaction.
  951. if err != tt.wantErr {
  952. t.Errorf("%s: got err %v, want %v", tt.desc, err, tt.wantErr)
  953. continue
  954. }
  955. if err != nil {
  956. continue
  957. }
  958. // Check the final value of the counter.
  959. if err := client.Get(ctx, key, c); err != nil {
  960. t.Errorf("%s: client.Get: %v", tt.desc, err)
  961. continue
  962. }
  963. if c.N != tt.want {
  964. t.Errorf("%s: counter N=%d, want N=%d", tt.desc, c.N, tt.want)
  965. }
  966. }
  967. }
  968. func TestReadOnlyTransaction(t *testing.T) {
  969. if testing.Short() {
  970. t.Skip("Integration tests skipped in short mode")
  971. }
  972. ctx := context.Background()
  973. client := newClient(ctx, t, nil)
  974. defer client.Close()
  975. type value struct{ N int }
  976. // Put a value.
  977. const n = 5
  978. v := &value{N: n}
  979. key, err := client.Put(ctx, IncompleteKey("roTxn", nil), v)
  980. if err != nil {
  981. t.Fatal(err)
  982. }
  983. defer client.Delete(ctx, key)
  984. // Read it from a read-only transaction.
  985. _, err = client.RunInTransaction(ctx, func(tx *Transaction) error {
  986. if err := tx.Get(key, v); err != nil {
  987. return err
  988. }
  989. return nil
  990. }, ReadOnly)
  991. if err != nil {
  992. t.Fatal(err)
  993. }
  994. if v.N != n {
  995. t.Fatalf("got %d, want %d", v.N, n)
  996. }
  997. // Attempting to write from a read-only transaction is an error.
  998. _, err = client.RunInTransaction(ctx, func(tx *Transaction) error {
  999. if _, err := tx.Put(key, v); err != nil {
  1000. return err
  1001. }
  1002. return nil
  1003. }, ReadOnly)
  1004. if err == nil {
  1005. t.Fatal("got nil, want error")
  1006. }
  1007. }
  1008. func TestNilPointers(t *testing.T) {
  1009. ctx := context.Background()
  1010. client := newTestClient(ctx, t)
  1011. defer client.Close()
  1012. type X struct {
  1013. S string
  1014. }
  1015. src := []*X{{"zero"}, {"one"}}
  1016. keys := []*Key{IncompleteKey("NilX", nil), IncompleteKey("NilX", nil)}
  1017. keys, err := client.PutMulti(ctx, keys, src)
  1018. if err != nil {
  1019. t.Fatalf("PutMulti: %v", err)
  1020. }
  1021. // It's okay to store into a slice of nil *X.
  1022. xs := make([]*X, 2)
  1023. if err := client.GetMulti(ctx, keys, xs); err != nil {
  1024. t.Errorf("GetMulti: %v", err)
  1025. } else if !testutil.Equal(xs, src) {
  1026. t.Errorf("GetMulti fetched %v, want %v", xs, src)
  1027. }
  1028. // It isn't okay to store into a single nil *X.
  1029. var x0 *X
  1030. if err, want := client.Get(ctx, keys[0], x0), ErrInvalidEntityType; err != want {
  1031. t.Errorf("Get: err %v; want %v", err, want)
  1032. }
  1033. // Test that deleting with duplicate keys work.
  1034. keys = append(keys, keys...)
  1035. if err := client.DeleteMulti(ctx, keys); err != nil {
  1036. t.Errorf("Delete: %v", err)
  1037. }
  1038. }
  1039. func TestNestedRepeatedElementNoIndex(t *testing.T) {
  1040. ctx := context.Background()
  1041. client := newTestClient(ctx, t)
  1042. defer client.Close()
  1043. type Inner struct {
  1044. Name string
  1045. Value string `datastore:",noindex"`
  1046. }
  1047. type Outer struct {
  1048. Config []Inner
  1049. }
  1050. m := &Outer{
  1051. Config: []Inner{
  1052. {Name: "short", Value: "a"},
  1053. {Name: "long", Value: strings.Repeat("a", 2000)},
  1054. },
  1055. }
  1056. key := NameKey("Nested", "Nested"+suffix, nil)
  1057. if _, err := client.Put(ctx, key, m); err != nil {
  1058. t.Fatalf("client.Put: %v", err)
  1059. }
  1060. if err := client.Delete(ctx, key); err != nil {
  1061. t.Fatalf("client.Delete: %v", err)
  1062. }
  1063. }
  1064. func TestPointerFields(t *testing.T) {
  1065. ctx := context.Background()
  1066. client := newTestClient(ctx, t)
  1067. defer client.Close()
  1068. want := populatedPointers()
  1069. key, err := client.Put(ctx, IncompleteKey("pointers", nil), want)
  1070. if err != nil {
  1071. t.Fatal(err)
  1072. }
  1073. var got Pointers
  1074. if err := client.Get(ctx, key, &got); err != nil {
  1075. t.Fatal(err)
  1076. }
  1077. if got.Pi == nil || *got.Pi != *want.Pi {
  1078. t.Errorf("Pi: got %v, want %v", got.Pi, *want.Pi)
  1079. }
  1080. if got.Ps == nil || *got.Ps != *want.Ps {
  1081. t.Errorf("Ps: got %v, want %v", got.Ps, *want.Ps)
  1082. }
  1083. if got.Pb == nil || *got.Pb != *want.Pb {
  1084. t.Errorf("Pb: got %v, want %v", got.Pb, *want.Pb)
  1085. }
  1086. if got.Pf == nil || *got.Pf != *want.Pf {
  1087. t.Errorf("Pf: got %v, want %v", got.Pf, *want.Pf)
  1088. }
  1089. if got.Pg == nil || *got.Pg != *want.Pg {
  1090. t.Errorf("Pg: got %v, want %v", got.Pg, *want.Pg)
  1091. }
  1092. if got.Pt == nil || !got.Pt.Equal(*want.Pt) {
  1093. t.Errorf("Pt: got %v, want %v", got.Pt, *want.Pt)
  1094. }
  1095. }
  1096. func TestMutate(t *testing.T) {
  1097. // test Client.Mutate
  1098. testMutate(t, func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error) {
  1099. return client.Mutate(ctx, muts...)
  1100. })
  1101. // test Transaction.Mutate
  1102. testMutate(t, func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error) {
  1103. var pkeys []*PendingKey
  1104. commit, err := client.RunInTransaction(ctx, func(tx *Transaction) error {
  1105. var err error
  1106. pkeys, err = tx.Mutate(muts...)
  1107. return err
  1108. })
  1109. if err != nil {
  1110. return nil, err
  1111. }
  1112. var keys []*Key
  1113. for _, pk := range pkeys {
  1114. keys = append(keys, commit.Key(pk))
  1115. }
  1116. return keys, nil
  1117. })
  1118. }
  1119. func testMutate(t *testing.T, mutate func(ctx context.Context, client *Client, muts ...*Mutation) ([]*Key, error)) {
  1120. ctx := context.Background()
  1121. client := newTestClient(ctx, t)
  1122. defer client.Close()
  1123. type T struct{ I int }
  1124. check := func(k *Key, want interface{}) {
  1125. var x T
  1126. err := client.Get(ctx, k, &x)
  1127. switch want := want.(type) {
  1128. case error:
  1129. if err != want {
  1130. t.Errorf("key %s: got error %v, want %v", k, err, want)
  1131. }
  1132. case int:
  1133. if err != nil {
  1134. t.Fatalf("key %s: %v", k, err)
  1135. }
  1136. if x.I != want {
  1137. t.Errorf("key %s: got %d, want %d", k, x.I, want)
  1138. }
  1139. default:
  1140. panic("check: bad arg")
  1141. }
  1142. }
  1143. keys, err := mutate(ctx, client,
  1144. NewInsert(IncompleteKey("t", nil), &T{1}),
  1145. NewUpsert(IncompleteKey("t", nil), &T{2}),
  1146. )
  1147. if err != nil {
  1148. t.Fatal(err)
  1149. }
  1150. check(keys[0], 1)
  1151. check(keys[1], 2)
  1152. _, err = mutate(ctx, client,
  1153. NewUpdate(keys[0], &T{3}),
  1154. NewDelete(keys[1]),
  1155. )
  1156. check(keys[0], 3)
  1157. check(keys[1], ErrNoSuchEntity)
  1158. _, err = mutate(ctx, client, NewInsert(keys[0], &T{4}))
  1159. if got, want := status.Code(err), codes.AlreadyExists; got != want {
  1160. t.Errorf("Insert existing key: got %s, want %s", got, want)
  1161. }
  1162. _, err = mutate(ctx, client, NewUpdate(keys[1], &T{4}))
  1163. if got, want := status.Code(err), codes.NotFound; got != want {
  1164. t.Errorf("Update non-existing key: got %s, want %s", got, want)
  1165. }
  1166. }