Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sync@v0.0.0-20200625203802-6e8e738ad208 / syncmap / map_test.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package syncmap_test
6
7 import (
8         "math/rand"
9         "reflect"
10         "runtime"
11         "sync"
12         "testing"
13         "testing/quick"
14
15         "golang.org/x/sync/syncmap"
16 )
17
18 type mapOp string
19
20 const (
21         opLoad        = mapOp("Load")
22         opStore       = mapOp("Store")
23         opLoadOrStore = mapOp("LoadOrStore")
24         opDelete      = mapOp("Delete")
25 )
26
27 var mapOps = [...]mapOp{opLoad, opStore, opLoadOrStore, opDelete}
28
29 // mapCall is a quick.Generator for calls on mapInterface.
30 type mapCall struct {
31         op   mapOp
32         k, v interface{}
33 }
34
35 func (c mapCall) apply(m mapInterface) (interface{}, bool) {
36         switch c.op {
37         case opLoad:
38                 return m.Load(c.k)
39         case opStore:
40                 m.Store(c.k, c.v)
41                 return nil, false
42         case opLoadOrStore:
43                 return m.LoadOrStore(c.k, c.v)
44         case opDelete:
45                 m.Delete(c.k)
46                 return nil, false
47         default:
48                 panic("invalid mapOp")
49         }
50 }
51
52 type mapResult struct {
53         value interface{}
54         ok    bool
55 }
56
57 func randValue(r *rand.Rand) interface{} {
58         b := make([]byte, r.Intn(4))
59         for i := range b {
60                 b[i] = 'a' + byte(rand.Intn(26))
61         }
62         return string(b)
63 }
64
65 func (mapCall) Generate(r *rand.Rand, size int) reflect.Value {
66         c := mapCall{op: mapOps[rand.Intn(len(mapOps))], k: randValue(r)}
67         switch c.op {
68         case opStore, opLoadOrStore:
69                 c.v = randValue(r)
70         }
71         return reflect.ValueOf(c)
72 }
73
74 func applyCalls(m mapInterface, calls []mapCall) (results []mapResult, final map[interface{}]interface{}) {
75         for _, c := range calls {
76                 v, ok := c.apply(m)
77                 results = append(results, mapResult{v, ok})
78         }
79
80         final = make(map[interface{}]interface{})
81         m.Range(func(k, v interface{}) bool {
82                 final[k] = v
83                 return true
84         })
85
86         return results, final
87 }
88
89 func applyMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) {
90         return applyCalls(new(syncmap.Map), calls)
91 }
92
93 func applyRWMutexMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) {
94         return applyCalls(new(RWMutexMap), calls)
95 }
96
97 func applyDeepCopyMap(calls []mapCall) ([]mapResult, map[interface{}]interface{}) {
98         return applyCalls(new(DeepCopyMap), calls)
99 }
100
101 func TestMapMatchesRWMutex(t *testing.T) {
102         if err := quick.CheckEqual(applyMap, applyRWMutexMap, nil); err != nil {
103                 t.Error(err)
104         }
105 }
106
107 func TestMapMatchesDeepCopy(t *testing.T) {
108         if err := quick.CheckEqual(applyMap, applyDeepCopyMap, nil); err != nil {
109                 t.Error(err)
110         }
111 }
112
113 func TestConcurrentRange(t *testing.T) {
114         const mapSize = 1 << 10
115
116         m := new(syncmap.Map)
117         for n := int64(1); n <= mapSize; n++ {
118                 m.Store(n, int64(n))
119         }
120
121         done := make(chan struct{})
122         var wg sync.WaitGroup
123         defer func() {
124                 close(done)
125                 wg.Wait()
126         }()
127         for g := int64(runtime.GOMAXPROCS(0)); g > 0; g-- {
128                 r := rand.New(rand.NewSource(g))
129                 wg.Add(1)
130                 go func(g int64) {
131                         defer wg.Done()
132                         for i := int64(0); ; i++ {
133                                 select {
134                                 case <-done:
135                                         return
136                                 default:
137                                 }
138                                 for n := int64(1); n < mapSize; n++ {
139                                         if r.Int63n(mapSize) == 0 {
140                                                 m.Store(n, n*i*g)
141                                         } else {
142                                                 m.Load(n)
143                                         }
144                                 }
145                         }
146                 }(g)
147         }
148
149         iters := 1 << 10
150         if testing.Short() {
151                 iters = 16
152         }
153         for n := iters; n > 0; n-- {
154                 seen := make(map[int64]bool, mapSize)
155
156                 m.Range(func(ki, vi interface{}) bool {
157                         k, v := ki.(int64), vi.(int64)
158                         if v%k != 0 {
159                                 t.Fatalf("while Storing multiples of %v, Range saw value %v", k, v)
160                         }
161                         if seen[k] {
162                                 t.Fatalf("Range visited key %v twice", k)
163                         }
164                         seen[k] = true
165                         return true
166                 })
167
168                 if len(seen) != mapSize {
169                         t.Fatalf("Range visited %v elements of %v-element Map", len(seen), mapSize)
170                 }
171         }
172 }