blob: d70750975bceefcf02b372698e138d4409a1988d [file] [log] [blame]
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -07001package namespace
2
3import (
4 "fmt"
5 "testing"
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -07006 "time"
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -07007
Jiri Simsa519c5072014-09-17 21:37:57 -07008 "veyron.io/veyron/veyron2/naming"
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -07009)
10
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070011func compatible(server string, servers []naming.MountedServer) bool {
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070012 if len(servers) == 0 {
13 return server == ""
14 }
15 return servers[0].Server == server
16}
17
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070018func future(secs uint32) time.Time {
19 return time.Now().Add(time.Duration(secs) * time.Second)
20}
21
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070022// TestCache tests the cache directly rather than via the namespace methods.
23func TestCache(t *testing.T) {
24 preload := []struct {
25 name string
26 suffix string
27 server string
28 }{
29 {"/h1//a/b/c/d", "c/d", "/h2"},
30 {"/h2//c/d", "d", "/h3"},
31 {"/h3//d", "", "/h4:1234"},
32 }
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -070033 c := newTTLCache()
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070034 for _, p := range preload {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070035 e := &naming.MountEntry{Name: p.suffix, Servers: []naming.MountedServer{naming.MountedServer{Server: p.server, Expires: future(30)}}}
36 c.remember(p.name, e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070037 }
38
39 tests := []struct {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070040 name string
41 suffix string
42 server string
43 succeed bool
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070044 }{
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070045 {"/h1//a/b/c/d", "c/d", "/h2", true},
46 {"/h2//c/d", "d", "/h3", true},
47 {"/h3//d", "", "/h4:1234", true},
48 {"/notintcache", "", "", false},
49 {"/h1//a/b/f//g", "f//g", "/h2", true},
50 {"/h3//d//e", "//e", "/h4:1234", true},
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070051 }
52 for _, p := range tests {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070053 e, err := c.lookup(p.name)
54 if (err == nil) != p.succeed {
55 t.Errorf("%s: lookup failed", p.name)
56 }
57 if e.Name != p.suffix || !compatible(p.server, e.Servers) {
58 t.Errorf("%s: got %v, %s not %s, %s", p.name, e.Name, e.Servers, p.suffix, p.server)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070059 }
60 }
61}
62
63func TestCacheLimit(t *testing.T) {
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -070064 c := newTTLCache().(*ttlCache)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070065 e := &naming.MountEntry{Servers: []naming.MountedServer{naming.MountedServer{Server: "the rain in spain", Expires: future(3000)}}}
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070066 for i := 0; i < maxCacheEntries; i++ {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070067 c.remember(fmt.Sprintf("%d", i), e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070068 if len(c.entries) > maxCacheEntries {
69 t.Errorf("unexpected cache size: got %d not %d", len(c.entries), maxCacheEntries)
70 }
71 }
72 // Adding one more element should reduce us to 3/4 full.
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070073 c.remember(fmt.Sprintf("%d", maxCacheEntries), e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070074 if len(c.entries) != cacheHisteresisSize {
75 t.Errorf("cache shrunk wrong amount: got %d not %d", len(c.entries), cacheHisteresisSize)
76 }
77}
78
79func TestCacheTTL(t *testing.T) {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070080 before := time.Now()
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -070081 c := newTTLCache().(*ttlCache)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070082 // Fill cache.
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070083 e := &naming.MountEntry{Servers: []naming.MountedServer{naming.MountedServer{Server: "the rain in spain", Expires: future(3000)}}}
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070084 for i := 0; i < maxCacheEntries; i++ {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070085 c.remember(fmt.Sprintf("%d", i), e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070086 }
87 // Time out half the entries.
88 i := len(c.entries) / 2
89 for k := range c.entries {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070090 c.entries[k].Servers[0].Expires = before
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070091 if i == 0 {
92 break
93 }
94 i--
95 }
96 // Add an entry and make sure we now have room.
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -070097 c.remember(fmt.Sprintf("%d", maxCacheEntries+2), e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -070098 if len(c.entries) > cacheHisteresisSize {
99 t.Errorf("entries did not timeout: got %d not %d", len(c.entries), cacheHisteresisSize)
100 }
101}
102
103func TestFlushCacheEntry(t *testing.T) {
104 preload := []struct {
105 name string
106 server string
107 }{
108 {"/h1//a/b", "/h2//c"},
109 {"/h2//c", "/h3"},
110 {"/h3//d", "/h4:1234"},
111 }
112 ns, _ := New(nil)
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700113 c := ns.resolutionCache.(*ttlCache)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -0700114 for _, p := range preload {
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700115 e := &naming.MountEntry{Servers: []naming.MountedServer{naming.MountedServer{Server: "p.server", Expires: future(3000)}}}
116 c.remember(p.name, e)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -0700117 }
118 toflush := "/h1/xyzzy"
119 if ns.FlushCacheEntry(toflush) {
120 t.Errorf("%s should not have caused anything to flush", toflush)
121 }
122 toflush = "/h1/a/b/d/e"
123 if !ns.FlushCacheEntry(toflush) {
124 t.Errorf("%s should have caused something to flush", toflush)
125 }
126 name := preload[2].name
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700127 if _, ok := c.entries[name]; !ok {
128 t.Errorf("%s should not have been flushed", name)
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -0700129 }
130 if len(c.entries) != 2 {
131 t.Errorf("%s flushed too many entries", toflush)
132 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700133 toflush = preload[1].name
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -0700134 if !ns.FlushCacheEntry(toflush) {
135 t.Errorf("%s should have caused something to flush", toflush)
136 }
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700137 if _, ok := c.entries[toflush]; ok {
David Why Use Two When One Will Do Presotto4f7161e2014-08-18 13:16:11 -0700138 t.Errorf("%s should have been flushed", name)
139 }
140 if len(c.entries) != 1 {
141 t.Errorf("%s flushed too many entries", toflush)
142 }
143}
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700144
145func disabled(ctls []naming.CacheCtl) bool {
146 for _, c := range ctls {
David Why Use Two When One Will Do Presotto185b0cd2014-08-22 12:12:31 -0700147 if v, ok := c.(naming.DisableCache); ok && bool(v) {
148 return true
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700149 }
150 }
151 return false
152}
153
154func TestCacheDisableEnable(t *testing.T) {
155 ns, _ := New(nil)
156
157 // Default should be working resolution cache.
158 name := "/h1//a"
159 serverName := "/h2//"
160 c := ns.resolutionCache.(*ttlCache)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700161 e := &naming.MountEntry{Servers: []naming.MountedServer{naming.MountedServer{Server: serverName, Expires: future(3000)}}}
162 c.remember(name, e)
163 if ne, err := c.lookup(name); err != nil || ne.Servers[0].Server != serverName {
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700164 t.Errorf("should have found the server in the cache")
165 }
166
167 // Turn off the resolution cache.
168 ctls := ns.CacheCtl(naming.DisableCache(true))
169 if !disabled(ctls) {
170 t.Errorf("caching not disabled")
171 }
172 nc := ns.resolutionCache.(nullCache)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700173 nc.remember(name, e)
174 if _, err := nc.lookup(name); err == nil {
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700175 t.Errorf("should not have found the server in the cache")
176 }
177
178 // Turn on the resolution cache.
179 ctls = ns.CacheCtl(naming.DisableCache(false))
180 if disabled(ctls) {
181 t.Errorf("caching disabled")
182 }
183 c = ns.resolutionCache.(*ttlCache)
David Why Use Two When One Will Do Presotto59a254c2014-10-30 13:09:29 -0700184 c.remember(name, e)
185 if ne, err := c.lookup(name); err != nil || ne.Servers[0].Server != serverName {
David Why Use Two When One Will Do Presotto7764f312014-08-20 16:24:05 -0700186 t.Errorf("should have found the server in the cache")
187 }
188}