Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package memory | |
| 6 | |
| 7 import ( | |
| 8 "sync" | |
| 9 "sync/atomic" | |
| 10 "testing" | |
| 11 | |
| 12 "github.com/luci/gae/service/datastore" | |
| 13 "golang.org/x/net/context" | |
| 14 ) | |
| 15 | |
| 16 func TestRaceGetPut(t *testing.T) { | |
| 17 t.Parallel() | |
| 18 | |
| 19 value := new(int64) | |
|
dnj
2015/11/10 00:20:20
nit: int64(0), use &value elsewhere.
iannucci
2015/11/11 18:13:58
*shrug*
| |
| 20 num := new(int64) | |
| 21 | |
| 22 ds := datastore.Get(Use(context.Background())) | |
| 23 | |
| 24 wg := sync.WaitGroup{} | |
| 25 | |
| 26 for i := 0; i < 100; i++ { | |
| 27 wg.Add(1) | |
| 28 go func() { | |
| 29 defer wg.Done() | |
| 30 | |
| 31 err := ds.RunInTransaction(func(c context.Context) error { | |
| 32 atomic.AddInt64(num, 1) | |
| 33 | |
| 34 ds := datastore.Get(c) | |
| 35 | |
| 36 obj := pmap("$key", ds.MakeKey("Obj", 1)) | |
| 37 if err := ds.Get(obj); err != nil && err != data store.ErrNoSuchEntity { | |
| 38 t.Fatal("error get", err) | |
| 39 } | |
| 40 cur := int64(0) | |
| 41 if ps, ok := obj["Value"]; ok { | |
| 42 cur = ps[0].Value().(int64) | |
| 43 } | |
| 44 | |
| 45 cur++ | |
| 46 obj["Value"] = []datastore.Property{prop(cur)} | |
| 47 | |
| 48 return ds.Put(obj) | |
| 49 }, &datastore.TransactionOptions{Attempts: 200}) | |
| 50 | |
| 51 if err != nil { | |
| 52 t.Fatal("error during transaction", err) | |
| 53 } | |
| 54 | |
| 55 atomic.AddInt64(value, 1) | |
|
dnj
2015/11/10 00:20:20
This may break on 32-bit systems b/c not allocated
iannucci
2015/11/11 18:13:58
it's allocated so it's fine
| |
| 56 }() | |
| 57 } | |
| 58 wg.Wait() | |
| 59 | |
| 60 obj := pmap("$key", ds.MakeKey("Obj", 1)) | |
| 61 if ds.Get(obj) != nil { | |
| 62 t.FailNow() | |
| 63 } | |
| 64 t.Logf("Ran %d inner functions", *num) | |
| 65 if *value != obj["Value"][0].Value().(int64) { | |
| 66 t.Fatalf("value wrong value %d v %d", *value, obj["Value"][0].Va lue().(int64)) | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 func TestRaceNonConflictingPuts(t *testing.T) { | |
| 71 t.Parallel() | |
| 72 | |
| 73 ds := datastore.Get(Use(context.Background())) | |
| 74 | |
| 75 num := new(int64) | |
|
dnj
2015/11/10 00:20:20
int64(0)
| |
| 76 | |
| 77 wg := sync.WaitGroup{} | |
| 78 | |
| 79 for i := 0; i < 100; i++ { | |
| 80 wg.Add(1) | |
| 81 go func() { | |
| 82 defer wg.Done() | |
| 83 | |
| 84 err := ds.RunInTransaction(func(c context.Context) error { | |
| 85 ds := datastore.Get(c) | |
| 86 return ds.Put(pmap( | |
| 87 "$kind", "Thing", Next, | |
| 88 "Value", 100)) | |
| 89 }, nil) | |
| 90 if err != nil { | |
| 91 t.Fatal("error during transaction", err) | |
| 92 } | |
| 93 atomic.AddInt64(num, 1) | |
| 94 }() | |
| 95 } | |
| 96 wg.Wait() | |
| 97 | |
| 98 if *num != 100 { | |
| 99 t.Fatal("expected 100 runs, got", *num) | |
| 100 } | |
| 101 } | |
| OLD | NEW |