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.CreateTestRepo(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	require.NoError(t, cache.load())
 87	require.Empty(t, cache.bugs)
 88	require.Empty(t, cache.identities)
 89	require.Len(t, cache.bugExcerpts, 2)
 90	require.Len(t, cache.identitiesExcerpts, 2)
 91
 92	// Resolving load from the disk
 93	_, err = cache.ResolveIdentity(iden1.Id())
 94	require.NoError(t, err)
 95	_, err = cache.ResolveIdentityExcerpt(iden1.Id())
 96	require.NoError(t, err)
 97	_, err = cache.ResolveIdentityPrefix(iden1.Id().String()[:10])
 98	require.NoError(t, err)
 99
100	_, err = cache.ResolveBug(bug1.Id())
101	require.NoError(t, err)
102	_, err = cache.ResolveBugExcerpt(bug1.Id())
103	require.NoError(t, err)
104	_, err = cache.ResolveBugPrefix(bug1.Id().String()[:10])
105	require.NoError(t, err)
106}
107
108func TestPushPull(t *testing.T) {
109	repoA, repoB, remote := repository.SetupReposAndRemote()
110	defer repository.CleanupTestRepos(repoA, repoB, remote)
111
112	cacheA, err := NewRepoCache(repoA)
113	require.NoError(t, err)
114
115	cacheB, err := NewRepoCache(repoB)
116	require.NoError(t, err)
117
118	// Create, set and get user identity
119	reneA, err := cacheA.NewIdentity("René Descartes", "rene@descartes.fr")
120	require.NoError(t, err)
121	err = cacheA.SetUserIdentity(reneA)
122	require.NoError(t, err)
123
124	// distribute the identity
125	_, err = cacheA.Push("origin")
126	require.NoError(t, err)
127	err = cacheB.Pull("origin")
128	require.NoError(t, err)
129
130	// Create a bug in A
131	_, _, err = cacheA.NewBug("bug1", "message")
132	require.NoError(t, err)
133
134	// A --> remote --> B
135	_, err = cacheA.Push("origin")
136	require.NoError(t, err)
137
138	err = cacheB.Pull("origin")
139	require.NoError(t, err)
140
141	require.Len(t, cacheB.AllBugsIds(), 1)
142
143	// retrieve and set identity
144	reneB, err := cacheB.ResolveIdentity(reneA.Id())
145	require.NoError(t, err)
146
147	err = cacheB.SetUserIdentity(reneB)
148	require.NoError(t, err)
149
150	// B --> remote --> A
151	_, _, err = cacheB.NewBug("bug2", "message")
152	require.NoError(t, err)
153
154	_, err = cacheB.Push("origin")
155	require.NoError(t, err)
156
157	err = cacheA.Pull("origin")
158	require.NoError(t, err)
159
160	require.Len(t, cacheA.AllBugsIds(), 2)
161}
162
163func TestRemove(t *testing.T) {
164	repo := repository.CreateTestRepo(false)
165	remoteA := repository.CreateTestRepo(true)
166	remoteB := repository.CreateTestRepo(true)
167	defer repository.CleanupTestRepos(repo, remoteA, remoteB)
168
169	err := repo.AddRemote("remoteA", "file://"+remoteA.GetPath())
170	require.NoError(t, err)
171
172	err = repo.AddRemote("remoteB", "file://"+remoteB.GetPath())
173	require.NoError(t, err)
174
175	repoCache, err := NewRepoCache(repo)
176	require.NoError(t, err)
177
178	// generate a bunch of bugs
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	for i := 0; i < 100; i++ {
186		_, _, err := repoCache.NewBug("title", "message")
187		require.NoError(t, err)
188	}
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, 100, len(repoCache.bugs))
209	assert.Equal(t, 100, 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.CreateTestRepo(false)
217	repoCache, err := NewRepoCache(repo)
218	require.NoError(t, err)
219	repoCache.presentBugs.Resize(2)
220
221	require.Equal(t, 0, repoCache.presentBugs.Len())
222	require.Equal(t, 0, len(repoCache.bugs))
223	require.Equal(t, 0, len(repoCache.bugExcerpts))
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.presentBugs.Len())
236	require.Equal(t, 1, len(repoCache.bugs))
237	require.Equal(t, 1, len(repoCache.bugExcerpts))
238
239	bug2, _, err := repoCache.NewBug("title", "message")
240	require.NoError(t, err)
241
242	checkBugPresence(t, repoCache, bug1, true)
243	checkBugPresence(t, repoCache, bug2, true)
244	require.Equal(t, 2, repoCache.presentBugs.Len())
245	require.Equal(t, 2, len(repoCache.bugs))
246	require.Equal(t, 2, len(repoCache.bugExcerpts))
247
248	// Number of bugs should not exceed max size of lruCache, oldest one should be evicted
249	bug3, _, err := repoCache.NewBug("title", "message")
250	require.NoError(t, err)
251
252	checkBugPresence(t, repoCache, bug1, false)
253	checkBugPresence(t, repoCache, bug2, true)
254	checkBugPresence(t, repoCache, bug3, true)
255	require.Equal(t, 2, repoCache.presentBugs.Len())
256	require.Equal(t, 2, len(repoCache.bugs))
257	require.Equal(t, 2, len(repoCache.bugExcerpts))
258
259	// Accessing bug should update position in lruCache and therefore it should not be evicted
260	repoCache.presentBugs.Get(bug2.Id())
261	oldestId, _ := repoCache.presentBugs.GetOldest()
262	require.Equal(t, bug3.Id(), oldestId)
263
264	checkBugPresence(t, repoCache, bug1, false)
265	checkBugPresence(t, repoCache, bug2, true)
266	checkBugPresence(t, repoCache, bug3, true)
267	require.Equal(t, 2, repoCache.presentBugs.Len())
268	require.Equal(t, 2, len(repoCache.bugs))
269	require.Equal(t, 2, len(repoCache.bugExcerpts))
270}
271
272func checkBugPresence(t *testing.T, cache *RepoCache, bug *BugCache, presence bool) {
273	id := bug.Id()
274	require.Equal(t, presence, cache.presentBugs.Contains(id))
275	b, ok := cache.bugs[id]
276	require.Equal(t, presence, ok)
277	require.Equal(t, bug, b)
278	_, ok = cache.bugExcerpts[id]
279	require.Equal(t, presence, ok)
280}