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 |