repo_cache_test.go

  1package cache
  2
  3import (
  4	"testing"
  5
  6	"github.com/stretchr/testify/assert"
  7	"github.com/stretchr/testify/require"
  8
  9	"github.com/MichaelMure/git-bug/bug"
 10	"github.com/MichaelMure/git-bug/query"
 11	"github.com/MichaelMure/git-bug/repository"
 12)
 13
 14func TestCache(t *testing.T) {
 15	repo := repository.CreateGoGitTestRepo(false)
 16	defer repository.CleanupTestRepos(repo)
 17
 18	cache, err := NewRepoCache(repo)
 19	require.NoError(t, err)
 20
 21	// Create, set and get user identity
 22	iden1, err := cache.NewIdentity("René Descartes", "rene@descartes.fr")
 23	require.NoError(t, err)
 24	err = cache.SetUserIdentity(iden1)
 25	require.NoError(t, err)
 26	userIden, err := cache.GetUserIdentity()
 27	require.NoError(t, err)
 28	require.Equal(t, iden1.Id(), userIden.Id())
 29
 30	// it's possible to create two identical identities
 31	iden2, err := cache.NewIdentity("René Descartes", "rene@descartes.fr")
 32	require.NoError(t, err)
 33
 34	// Two identical identities yield a different id
 35	require.NotEqual(t, iden1.Id(), iden2.Id())
 36
 37	// There is now two identities in the cache
 38	require.Len(t, cache.AllIdentityIds(), 2)
 39	require.Len(t, cache.identitiesExcerpts, 2)
 40	require.Len(t, cache.identities, 2)
 41
 42	// Create a bug
 43	bug1, _, err := cache.NewBug("title", "message")
 44	require.NoError(t, err)
 45
 46	// It's possible to create two identical bugs
 47	bug2, _, err := cache.NewBug("title", "message")
 48	require.NoError(t, err)
 49
 50	// two identical bugs yield a different id
 51	require.NotEqual(t, bug1.Id(), bug2.Id())
 52
 53	// There is now two bugs in the cache
 54	require.Len(t, cache.AllBugsIds(), 2)
 55	require.Len(t, cache.bugExcerpts, 2)
 56	require.Len(t, cache.bugs, 2)
 57
 58	// Resolving
 59	_, err = cache.ResolveIdentity(iden1.Id())
 60	require.NoError(t, err)
 61	_, err = cache.ResolveIdentityExcerpt(iden1.Id())
 62	require.NoError(t, err)
 63	_, err = cache.ResolveIdentityPrefix(iden1.Id().String()[:10])
 64	require.NoError(t, err)
 65
 66	_, err = cache.ResolveBug(bug1.Id())
 67	require.NoError(t, err)
 68	_, err = cache.ResolveBugExcerpt(bug1.Id())
 69	require.NoError(t, err)
 70	_, err = cache.ResolveBugPrefix(bug1.Id().String()[:10])
 71	require.NoError(t, err)
 72
 73	// Querying
 74	q, err := query.Parse("status:open author:descartes sort:edit-asc")
 75	require.NoError(t, err)
 76	require.Len(t, cache.QueryBugs(q), 2)
 77
 78	// Close
 79	require.NoError(t, cache.Close())
 80	require.Empty(t, cache.bugs)
 81	require.Empty(t, cache.bugExcerpts)
 82	require.Empty(t, cache.identities)
 83	require.Empty(t, cache.identitiesExcerpts)
 84
 85	// Reload, only excerpt are loaded
 86	cache, err = NewRepoCache(repo)
 87	require.NoError(t, err)
 88	require.Empty(t, cache.bugs)
 89	require.Empty(t, cache.identities)
 90	require.Len(t, cache.bugExcerpts, 2)
 91	require.Len(t, cache.identitiesExcerpts, 2)
 92
 93	// Resolving load from the disk
 94	_, err = cache.ResolveIdentity(iden1.Id())
 95	require.NoError(t, err)
 96	_, err = cache.ResolveIdentityExcerpt(iden1.Id())
 97	require.NoError(t, err)
 98	_, err = cache.ResolveIdentityPrefix(iden1.Id().String()[:10])
 99	require.NoError(t, err)
100
101	_, err = cache.ResolveBug(bug1.Id())
102	require.NoError(t, err)
103	_, err = cache.ResolveBugExcerpt(bug1.Id())
104	require.NoError(t, err)
105	_, err = cache.ResolveBugPrefix(bug1.Id().String()[:10])
106	require.NoError(t, err)
107}
108
109func TestPushPull(t *testing.T) {
110	repoA, repoB, remote := repository.SetupReposAndRemote()
111	defer repository.CleanupTestRepos(repoA, repoB, remote)
112
113	cacheA, err := NewRepoCache(repoA)
114	require.NoError(t, err)
115
116	cacheB, err := NewRepoCache(repoB)
117	require.NoError(t, err)
118
119	// Create, set and get user identity
120	reneA, err := cacheA.NewIdentity("René Descartes", "rene@descartes.fr")
121	require.NoError(t, err)
122	err = cacheA.SetUserIdentity(reneA)
123	require.NoError(t, err)
124
125	// distribute the identity
126	_, err = cacheA.Push("origin")
127	require.NoError(t, err)
128	err = cacheB.Pull("origin")
129	require.NoError(t, err)
130
131	// Create a bug in A
132	_, _, err = cacheA.NewBug("bug1", "message")
133	require.NoError(t, err)
134
135	// A --> remote --> B
136	_, err = cacheA.Push("origin")
137	require.NoError(t, err)
138
139	err = cacheB.Pull("origin")
140	require.NoError(t, err)
141
142	require.Len(t, cacheB.AllBugsIds(), 1)
143
144	// retrieve and set identity
145	reneB, err := cacheB.ResolveIdentity(reneA.Id())
146	require.NoError(t, err)
147
148	err = cacheB.SetUserIdentity(reneB)
149	require.NoError(t, err)
150
151	// B --> remote --> A
152	_, _, err = cacheB.NewBug("bug2", "message")
153	require.NoError(t, err)
154
155	_, err = cacheB.Push("origin")
156	require.NoError(t, err)
157
158	err = cacheA.Pull("origin")
159	require.NoError(t, err)
160
161	require.Len(t, cacheA.AllBugsIds(), 2)
162}
163
164func TestRemove(t *testing.T) {
165	repo := repository.CreateGoGitTestRepo(false)
166	remoteA := repository.CreateGoGitTestRepo(true)
167	remoteB := repository.CreateGoGitTestRepo(true)
168	defer repository.CleanupTestRepos(repo, remoteA, remoteB)
169
170	err := repo.AddRemote("remoteA", remoteA.GetPath())
171	require.NoError(t, err)
172
173	err = repo.AddRemote("remoteB", remoteB.GetPath())
174	require.NoError(t, err)
175
176	repoCache, err := NewRepoCache(repo)
177	require.NoError(t, err)
178
179	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
180	require.NoError(t, err)
181
182	err = repoCache.SetUserIdentity(rene)
183	require.NoError(t, err)
184
185	_, _, err = repoCache.NewBug("title", "message")
186	require.NoError(t, err)
187
188	// and one more for testing
189	b1, _, err := repoCache.NewBug("title", "message")
190	require.NoError(t, err)
191
192	_, err = repoCache.Push("remoteA")
193	require.NoError(t, err)
194
195	_, err = repoCache.Push("remoteB")
196	require.NoError(t, err)
197
198	_, err = repoCache.Fetch("remoteA")
199	require.NoError(t, err)
200
201	_, err = repoCache.Fetch("remoteB")
202	require.NoError(t, err)
203
204	err = repoCache.RemoveBug(b1.Id().String())
205	require.NoError(t, err)
206	assert.Equal(t, 1, len(repoCache.bugs))
207	assert.Equal(t, 1, len(repoCache.bugExcerpts))
208
209	_, err = repoCache.ResolveBug(b1.Id())
210	assert.Error(t, bug.ErrBugNotExist, err)
211}
212
213func TestCacheEviction(t *testing.T) {
214	repo := repository.CreateGoGitTestRepo(false)
215	repoCache, err := NewRepoCache(repo)
216	require.NoError(t, err)
217	repoCache.setCacheSize(2)
218
219	require.Equal(t, 2, repoCache.maxLoadedBugs)
220	require.Equal(t, 0, repoCache.loadedBugs.Len())
221	require.Equal(t, 0, len(repoCache.bugs))
222
223	// Generating some bugs
224	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
225	require.NoError(t, err)
226	err = repoCache.SetUserIdentity(rene)
227	require.NoError(t, err)
228
229	bug1, _, err := repoCache.NewBug("title", "message")
230	require.NoError(t, err)
231
232	checkBugPresence(t, repoCache, bug1, true)
233	require.Equal(t, 1, repoCache.loadedBugs.Len())
234	require.Equal(t, 1, len(repoCache.bugs))
235
236	bug2, _, err := repoCache.NewBug("title", "message")
237	require.NoError(t, err)
238
239	checkBugPresence(t, repoCache, bug1, true)
240	checkBugPresence(t, repoCache, bug2, true)
241	require.Equal(t, 2, repoCache.loadedBugs.Len())
242	require.Equal(t, 2, len(repoCache.bugs))
243
244	// Number of bugs should not exceed max size of lruCache, oldest one should be evicted
245	bug3, _, err := repoCache.NewBug("title", "message")
246	require.NoError(t, err)
247
248	require.Equal(t, 2, repoCache.loadedBugs.Len())
249	require.Equal(t, 2, len(repoCache.bugs))
250	checkBugPresence(t, repoCache, bug1, false)
251	checkBugPresence(t, repoCache, bug2, true)
252	checkBugPresence(t, repoCache, bug3, true)
253
254	// Accessing bug should update position in lruCache and therefore it should not be evicted
255	repoCache.loadedBugs.Get(bug2.Id())
256	oldestId, _ := repoCache.loadedBugs.GetOldest()
257	require.Equal(t, bug3.Id(), oldestId)
258
259	checkBugPresence(t, repoCache, bug1, false)
260	checkBugPresence(t, repoCache, bug2, true)
261	checkBugPresence(t, repoCache, bug3, true)
262	require.Equal(t, 2, repoCache.loadedBugs.Len())
263	require.Equal(t, 2, len(repoCache.bugs))
264}
265
266func checkBugPresence(t *testing.T, cache *RepoCache, bug *BugCache, presence bool) {
267	id := bug.Id()
268	require.Equal(t, presence, cache.loadedBugs.Contains(id))
269	b, ok := cache.bugs[id]
270	require.Equal(t, presence, ok)
271	if ok {
272		require.Equal(t, bug, b)
273	}
274}