blob: b0ee8eb73d0833871f901b6783f8c4725aa48b31 [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium 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
Matt Rosencrantz94502cf2015-03-18 09:43:44 -07005package rpc
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -07006
7import (
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -07008 "sort"
9 "sync"
10 "testing"
Jiri Simsa870ddd62014-06-27 14:56:58 -070011
Cosmos Nicolaou1381f8a2015-03-13 09:40:34 -070012 "v.io/x/ref/test/testutil"
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -070013)
14
15func randomKeys() []uint64 {
Cosmos Nicolaoua18a1eb2015-03-12 13:15:01 -070016 n := (testutil.Intn(256*10) / 10) + 256
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -070017 k := make([]uint64, n)
18 for i := 0; i < n; i++ {
Cosmos Nicolaoua18a1eb2015-03-12 13:15:01 -070019 k[i] = uint64(testutil.Int63())
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -070020 }
21 return k
22}
23
24type keySlice []uint64
25
26func (p keySlice) Len() int { return len(p) }
27func (p keySlice) Less(i, j int) bool { return p[i] < p[j] }
28func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
29func (p keySlice) Sort() { sort.Sort(p) }
30
31func TestStoreRandom(t *testing.T) {
32 store := newStore()
33 keys := randomKeys()
34
35 for i := 0; i < len(keys); i++ {
36 r := []interface{}{i}
37 store.addEntry(keys[i], r)
38 }
39 if len(store.store) != len(keys) {
40 t.Errorf("num stored entries: got %d, want %d", len(store.store), len(keys))
41 }
42 for i := 0; i < len(keys); i++ {
43 // Each call to removeEntries will remove an unknown number of entries
44 // depending on the original randomised value of the ints.
45 store.removeEntriesTo(keys[i])
46 }
47 if len(store.store) != 0 {
48 t.Errorf("store is not empty: %d", len(store.store))
49 }
50}
51
52func TestStoreOrdered(t *testing.T) {
53 store := newStore()
54 keys := randomKeys()
55
56 for i := 0; i < len(keys); i++ {
57 r := []interface{}{i}
58 store.addEntry(keys[i], r)
59 }
60 if len(store.store) != len(keys) {
61 t.Errorf("num stored entries: got %d, want %d", len(store.store), len(keys))
62 }
63
64 (keySlice(keys)).Sort()
65 l := len(keys)
66 for i := 0; i < len(keys); i++ {
67 store.removeEntriesTo(keys[i])
68 l--
69 if len(store.store) != l {
70 t.Errorf("failed to remove a single item(%d): %d != %d", keys[i], len(store.store), l)
71 }
72 }
73 if len(store.store) != 0 {
74 t.Errorf("store is not empty: %d", len(store.store))
75 }
76}
77
78func TestStoreWaitForEntry(t *testing.T) {
79 store := newStore()
80 store.addEntry(1, []interface{}{"1"})
81 r := store.waitForEntry(1)
82 if r[0].(string) != "1" {
83 t.Errorf("Got: %q, Want: %q", r[0], "1")
84 }
85 ch := make(chan string)
86 go func(ch chan string) {
87 r := store.waitForEntry(2)
88 ch <- r[0].(string)
89 }(ch)
90 store.addEntry(2, []interface{}{"2"})
91 if result := <-ch; result != "2" {
92 t.Errorf("Got: %q, Want: %q", r[0], "2")
93 }
94}
95
96func TestStoreWaitForEntryRandom(t *testing.T) {
97 store := newStore()
98 keys := randomKeys()
99 var wg sync.WaitGroup
100 for _, k := range keys {
101 wg.Add(1)
102 go func(t *testing.T, id uint64) {
103 r := store.waitForEntry(id)
104 if r[0].(uint64) != id {
105 t.Errorf("Got: %d, Want: %d", r[0].(uint64), id)
106 }
107 wg.Done()
108 }(t, k)
109 }
110 (keySlice(keys)).Sort()
111 for _, k := range keys {
112 store.addEntry(k, []interface{}{k})
113 }
114 wg.Wait()
115}
116
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -0700117func TestStoreWaitForRemovedEntry(t *testing.T) {
118 store := newStore()
119 keys := randomKeys()
120 var wg sync.WaitGroup
121 for _, k := range keys {
122 wg.Add(1)
123 go func(t *testing.T, id uint64) {
Asim Shankarc14225c2014-05-23 17:18:36 -0700124 if r := store.waitForEntry(id); r != nil {
125 t.Errorf("Got %v, want nil", r)
Cosmos Nicolaou174a44e2014-05-16 13:59:30 -0700126 }
127 wg.Done()
128 }(t, k)
129 }
130 (keySlice(keys)).Sort()
131 for _, k := range keys {
132 store.removeEntriesTo(k)
133 }
134 wg.Wait()
135}
Asim Shankarc14225c2014-05-23 17:18:36 -0700136
137func TestStoreWaitForOldEntry(t *testing.T) {
138 store := newStore()
139 store.addEntry(1, []interface{}{"result"})
140 store.removeEntriesTo(1)
141 if got := store.waitForEntry(1); got != nil {
142 t.Errorf("Got %T=%v, want nil", got, got)
143 }
144}