1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
7	"sync"
8	"testing"
9	"time"
10)
11
12func randChainLink() ChainLink {
13	id, err := RandBytes(LinkIDLen)
14	if err != nil {
15		panic(err)
16	}
17	return ChainLink{
18		id: LinkID(id),
19	}
20}
21
22func TestLinkCacheBasics(t *testing.T) {
23	c := NewLinkCache(10, time.Hour)
24	defer c.Shutdown()
25
26	link := randChainLink()
27
28	// Dangerous, but as long as it works for now, go with it...
29	var m MetaContext
30
31	c.Put(m, link.id, link)
32
33	if c.Len() != 1 {
34		t.Errorf("c.cache len: %d, expected 1", c.Len())
35	}
36
37	_, ok := c.Get(link.id)
38	if !ok {
39		t.Errorf("Get failed after Put")
40	}
41
42	for i := 0; i < 50; i++ {
43		nlink := randChainLink()
44		c.Put(m, nlink.id, nlink)
45	}
46
47	if c.Len() != 51 {
48		t.Errorf("c.cache len: %d, expected 51", c.Len())
49	}
50
51	c.Clean()
52
53	if c.Len() != 10 {
54		t.Errorf("c.cache len: %d, expected 10", c.Len())
55	}
56
57	// the first inserted link should be gone
58	_, ok = c.Get(link.id)
59	if ok {
60		t.Errorf("expected first link to be gone")
61	}
62}
63
64func TestLinkCacheAtime(t *testing.T) {
65	c := NewLinkCache(10, time.Hour)
66	defer c.Shutdown()
67
68	// Dangerous, but as long as it works for now, go with it...
69	var m MetaContext
70
71	link := randChainLink()
72	c.Put(m, link.id, link)
73
74	if c.Len() != 1 {
75		t.Errorf("c.cache len: %d, expected 1", c.Len())
76	}
77
78	_, ok := c.Get(link.id)
79	if !ok {
80		t.Errorf("Get failed after Put")
81	}
82
83	for i := 0; i < 50; i++ {
84		nlink := randChainLink()
85		c.Put(m, nlink.id, nlink)
86	}
87
88	// get the first inserted one to make it LRU
89	_, ok = c.Get(link.id)
90	if !ok {
91		t.Errorf("Get failed after Put of 50")
92	}
93
94	if c.Len() != 51 {
95		t.Errorf("c.cache len: %d, expected 51", c.Len())
96	}
97
98	c.Clean()
99
100	if c.Len() != 10 {
101		t.Errorf("c.cache len: %d, expected 10", c.Len())
102	}
103
104	// the first inserted link should still be there
105	_, ok = c.Get(link.id)
106	if !ok {
107		t.Errorf("expected first link to be cached")
108	}
109}
110
111// mainly useful when run with -race flag
112func TestLinkCacheConcurrent(t *testing.T) {
113	c := NewLinkCache(10, time.Hour)
114	defer c.Shutdown()
115
116	// Dangerous, but as long as it works for now, go with it...
117	var m MetaContext
118
119	var wg sync.WaitGroup
120	for i := 0; i < 10; i++ {
121		wg.Add(1)
122		go func() {
123			for x := 0; x < 100; x++ {
124				link := randChainLink()
125				c.Put(m, link.id, link)
126				_, ok := c.Get(link.id)
127				if !ok {
128					t.Errorf("concurrent Get failed")
129				}
130			}
131			wg.Done()
132		}()
133	}
134	wg.Wait()
135}
136
137func TestLinkCacheShutdown(t *testing.T) {
138	c := NewLinkCache(10, time.Hour)
139	c.Shutdown()
140	c.Shutdown()
141}
142