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	res, err := cache.QueryBugs(q)
 77	require.NoError(t, err)
 78	require.Len(t, res, 2)
 79
 80	// Close
 81	require.NoError(t, cache.Close())
 82	require.Empty(t, cache.bugs)
 83	require.Empty(t, cache.bugExcerpts)
 84	require.Empty(t, cache.identities)
 85	require.Empty(t, cache.identitiesExcerpts)
 86
 87	// Reload, only excerpt are loaded
 88	cache, err = NewRepoCache(repo)
 89	require.NoError(t, err)
 90	require.Empty(t, cache.bugs)
 91	require.Empty(t, cache.identities)
 92	require.Len(t, cache.bugExcerpts, 2)
 93	require.Len(t, cache.identitiesExcerpts, 2)
 94
 95	// Resolving load from the disk
 96	_, err = cache.ResolveIdentity(iden1.Id())
 97	require.NoError(t, err)
 98	_, err = cache.ResolveIdentityExcerpt(iden1.Id())
 99	require.NoError(t, err)
100	_, err = cache.ResolveIdentityPrefix(iden1.Id().String()[:10])
101	require.NoError(t, err)
102
103	_, err = cache.ResolveBug(bug1.Id())
104	require.NoError(t, err)
105	_, err = cache.ResolveBugExcerpt(bug1.Id())
106	require.NoError(t, err)
107	_, err = cache.ResolveBugPrefix(bug1.Id().String()[:10])
108	require.NoError(t, err)
109}
110
111func TestCachePushPull(t *testing.T) {
112	repoA, repoB, remote := repository.SetupGoGitReposAndRemote()
113	defer repository.CleanupTestRepos(repoA, repoB, remote)
114
115	cacheA, err := NewRepoCache(repoA)
116	require.NoError(t, err)
117
118	cacheB, err := NewRepoCache(repoB)
119	require.NoError(t, err)
120
121	// Create, set and get user identity
122	reneA, err := cacheA.NewIdentity("René Descartes", "rene@descartes.fr")
123	require.NoError(t, err)
124	err = cacheA.SetUserIdentity(reneA)
125	require.NoError(t, err)
126	isaacB, err := cacheB.NewIdentity("Isaac Newton", "isaac@newton.uk")
127	require.NoError(t, err)
128	err = cacheB.SetUserIdentity(isaacB)
129	require.NoError(t, err)
130
131	// distribute the identity
132	_, err = cacheA.Push("origin")
133	require.NoError(t, err)
134	err = cacheB.Pull("origin")
135	require.NoError(t, err)
136
137	// Create a bug in A
138	_, _, err = cacheA.NewBug("bug1", "message")
139	require.NoError(t, err)
140
141	// A --> remote --> B
142	_, err = cacheA.Push("origin")
143	require.NoError(t, err)
144
145	err = cacheB.Pull("origin")
146	require.NoError(t, err)
147
148	require.Len(t, cacheB.AllBugsIds(), 1)
149
150	// retrieve and set identity
151	reneB, err := cacheB.ResolveIdentity(reneA.Id())
152	require.NoError(t, err)
153
154	err = cacheB.SetUserIdentity(reneB)
155	require.NoError(t, err)
156
157	// B --> remote --> A
158	_, _, err = cacheB.NewBug("bug2", "message")
159	require.NoError(t, err)
160
161	_, err = cacheB.Push("origin")
162	require.NoError(t, err)
163
164	err = cacheA.Pull("origin")
165	require.NoError(t, err)
166
167	require.Len(t, cacheA.AllBugsIds(), 2)
168}
169
170func TestRemove(t *testing.T) {
171	repo := repository.CreateGoGitTestRepo(false)
172	remoteA := repository.CreateGoGitTestRepo(true)
173	remoteB := repository.CreateGoGitTestRepo(true)
174	defer repository.CleanupTestRepos(repo, remoteA, remoteB)
175
176	err := repo.AddRemote("remoteA", remoteA.GetLocalRemote())
177	require.NoError(t, err)
178
179	err = repo.AddRemote("remoteB", remoteB.GetLocalRemote())
180	require.NoError(t, err)
181
182	repoCache, err := NewRepoCache(repo)
183	require.NoError(t, err)
184
185	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
186	require.NoError(t, err)
187
188	err = repoCache.SetUserIdentity(rene)
189	require.NoError(t, err)
190
191	_, _, err = repoCache.NewBug("title", "message")
192	require.NoError(t, err)
193
194	// and one more for testing
195	b1, _, err := repoCache.NewBug("title", "message")
196	require.NoError(t, err)
197
198	_, err = repoCache.Push("remoteA")
199	require.NoError(t, err)
200
201	_, err = repoCache.Push("remoteB")
202	require.NoError(t, err)
203
204	_, err = repoCache.Fetch("remoteA")
205	require.NoError(t, err)
206
207	_, err = repoCache.Fetch("remoteB")
208	require.NoError(t, err)
209
210	err = repoCache.RemoveBug(b1.Id().String())
211	require.NoError(t, err)
212	assert.Equal(t, 1, len(repoCache.bugs))
213	assert.Equal(t, 1, len(repoCache.bugExcerpts))
214
215	_, err = repoCache.ResolveBug(b1.Id())
216	assert.Error(t, bug.ErrBugNotExist, err)
217}
218
219func TestCacheEviction(t *testing.T) {
220	repo := repository.CreateGoGitTestRepo(false)
221	repoCache, err := NewRepoCache(repo)
222	require.NoError(t, err)
223	repoCache.setCacheSize(2)
224
225	require.Equal(t, 2, repoCache.maxLoadedBugs)
226	require.Equal(t, 0, repoCache.loadedBugs.Len())
227	require.Equal(t, 0, len(repoCache.bugs))
228
229	// Generating some bugs
230	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
231	require.NoError(t, err)
232	err = repoCache.SetUserIdentity(rene)
233	require.NoError(t, err)
234
235	bug1, _, err := repoCache.NewBug("title", "message")
236	require.NoError(t, err)
237
238	checkBugPresence(t, repoCache, bug1, true)
239	require.Equal(t, 1, repoCache.loadedBugs.Len())
240	require.Equal(t, 1, len(repoCache.bugs))
241
242	bug2, _, err := repoCache.NewBug("title", "message")
243	require.NoError(t, err)
244
245	checkBugPresence(t, repoCache, bug1, true)
246	checkBugPresence(t, repoCache, bug2, true)
247	require.Equal(t, 2, repoCache.loadedBugs.Len())
248	require.Equal(t, 2, len(repoCache.bugs))
249
250	// Number of bugs should not exceed max size of lruCache, oldest one should be evicted
251	bug3, _, err := repoCache.NewBug("title", "message")
252	require.NoError(t, err)
253
254	require.Equal(t, 2, repoCache.loadedBugs.Len())
255	require.Equal(t, 2, len(repoCache.bugs))
256	checkBugPresence(t, repoCache, bug1, false)
257	checkBugPresence(t, repoCache, bug2, true)
258	checkBugPresence(t, repoCache, bug3, true)
259
260	// Accessing bug should update position in lruCache and therefore it should not be evicted
261	repoCache.loadedBugs.Get(bug2.Id())
262	oldestId, _ := repoCache.loadedBugs.GetOldest()
263	require.Equal(t, bug3.Id(), oldestId)
264
265	checkBugPresence(t, repoCache, bug1, false)
266	checkBugPresence(t, repoCache, bug2, true)
267	checkBugPresence(t, repoCache, bug3, true)
268	require.Equal(t, 2, repoCache.loadedBugs.Len())
269	require.Equal(t, 2, len(repoCache.bugs))
270}
271
272func checkBugPresence(t *testing.T, cache *RepoCache, bug *BugCache, presence bool) {
273	id := bug.Id()
274	require.Equal(t, presence, cache.loadedBugs.Contains(id))
275	b, ok := cache.bugs[id]
276	require.Equal(t, presence, ok)
277	if ok {
278		require.Equal(t, bug, b)
279	}
280}