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 TestPushPull(t *testing.T) {
112	repoA, repoB, remote := repository.SetupReposAndRemote()
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
127	// distribute the identity
128	_, err = cacheA.Push("origin")
129	require.NoError(t, err)
130	err = cacheB.Pull("origin")
131	require.NoError(t, err)
132
133	// Create a bug in A
134	_, _, err = cacheA.NewBug("bug1", "message")
135	require.NoError(t, err)
136
137	// A --> remote --> B
138	_, err = cacheA.Push("origin")
139	require.NoError(t, err)
140
141	err = cacheB.Pull("origin")
142	require.NoError(t, err)
143
144	require.Len(t, cacheB.AllBugsIds(), 1)
145
146	// retrieve and set identity
147	reneB, err := cacheB.ResolveIdentity(reneA.Id())
148	require.NoError(t, err)
149
150	err = cacheB.SetUserIdentity(reneB)
151	require.NoError(t, err)
152
153	// B --> remote --> A
154	_, _, err = cacheB.NewBug("bug2", "message")
155	require.NoError(t, err)
156
157	_, err = cacheB.Push("origin")
158	require.NoError(t, err)
159
160	err = cacheA.Pull("origin")
161	require.NoError(t, err)
162
163	require.Len(t, cacheA.AllBugsIds(), 2)
164}
165
166func TestRemove(t *testing.T) {
167	repo := repository.CreateGoGitTestRepo(false)
168	remoteA := repository.CreateGoGitTestRepo(true)
169	remoteB := repository.CreateGoGitTestRepo(true)
170	defer repository.CleanupTestRepos(repo, remoteA, remoteB)
171
172	err := repo.AddRemote("remoteA", remoteA.GetLocalRemote())
173	require.NoError(t, err)
174
175	err = repo.AddRemote("remoteB", remoteB.GetLocalRemote())
176	require.NoError(t, err)
177
178	repoCache, err := NewRepoCache(repo)
179	require.NoError(t, err)
180
181	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
182	require.NoError(t, err)
183
184	err = repoCache.SetUserIdentity(rene)
185	require.NoError(t, err)
186
187	_, _, err = repoCache.NewBug("title", "message")
188	require.NoError(t, err)
189
190	// and one more for testing
191	b1, _, err := repoCache.NewBug("title", "message")
192	require.NoError(t, err)
193
194	_, err = repoCache.Push("remoteA")
195	require.NoError(t, err)
196
197	_, err = repoCache.Push("remoteB")
198	require.NoError(t, err)
199
200	_, err = repoCache.Fetch("remoteA")
201	require.NoError(t, err)
202
203	_, err = repoCache.Fetch("remoteB")
204	require.NoError(t, err)
205
206	err = repoCache.RemoveBug(b1.Id().String())
207	require.NoError(t, err)
208	assert.Equal(t, 1, len(repoCache.bugs))
209	assert.Equal(t, 1, len(repoCache.bugExcerpts))
210
211	_, err = repoCache.ResolveBug(b1.Id())
212	assert.Error(t, bug.ErrBugNotExist, err)
213}
214
215func TestCacheEviction(t *testing.T) {
216	repo := repository.CreateGoGitTestRepo(false)
217	repoCache, err := NewRepoCache(repo)
218	require.NoError(t, err)
219	repoCache.setCacheSize(2)
220
221	require.Equal(t, 2, repoCache.maxLoadedBugs)
222	require.Equal(t, 0, repoCache.loadedBugs.Len())
223	require.Equal(t, 0, len(repoCache.bugs))
224
225	// Generating some bugs
226	rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
227	require.NoError(t, err)
228	err = repoCache.SetUserIdentity(rene)
229	require.NoError(t, err)
230
231	bug1, _, err := repoCache.NewBug("title", "message")
232	require.NoError(t, err)
233
234	checkBugPresence(t, repoCache, bug1, true)
235	require.Equal(t, 1, repoCache.loadedBugs.Len())
236	require.Equal(t, 1, len(repoCache.bugs))
237
238	bug2, _, err := repoCache.NewBug("title", "message")
239	require.NoError(t, err)
240
241	checkBugPresence(t, repoCache, bug1, true)
242	checkBugPresence(t, repoCache, bug2, true)
243	require.Equal(t, 2, repoCache.loadedBugs.Len())
244	require.Equal(t, 2, len(repoCache.bugs))
245
246	// Number of bugs should not exceed max size of lruCache, oldest one should be evicted
247	bug3, _, err := repoCache.NewBug("title", "message")
248	require.NoError(t, err)
249
250	require.Equal(t, 2, repoCache.loadedBugs.Len())
251	require.Equal(t, 2, len(repoCache.bugs))
252	checkBugPresence(t, repoCache, bug1, false)
253	checkBugPresence(t, repoCache, bug2, true)
254	checkBugPresence(t, repoCache, bug3, true)
255
256	// Accessing bug should update position in lruCache and therefore it should not be evicted
257	repoCache.loadedBugs.Get(bug2.Id())
258	oldestId, _ := repoCache.loadedBugs.GetOldest()
259	require.Equal(t, bug3.Id(), oldestId)
260
261	checkBugPresence(t, repoCache, bug1, false)
262	checkBugPresence(t, repoCache, bug2, true)
263	checkBugPresence(t, repoCache, bug3, true)
264	require.Equal(t, 2, repoCache.loadedBugs.Len())
265	require.Equal(t, 2, len(repoCache.bugs))
266}
267
268func checkBugPresence(t *testing.T, cache *RepoCache, bug *BugCache, presence bool) {
269	id := bug.Id()
270	require.Equal(t, presence, cache.loadedBugs.Contains(id))
271	b, ok := cache.bugs[id]
272	require.Equal(t, presence, ok)
273	if ok {
274		require.Equal(t, bug, b)
275	}
276}