~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ngit/NGit.Test/NGit.Storage.File/GCTest.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This code is derived from jgit (http://eclipse.org/jgit).
 
3
Copyright owners are documented in jgit's IP log.
 
4
 
 
5
This program and the accompanying materials are made available
 
6
under the terms of the Eclipse Distribution License v1.0 which
 
7
accompanies this distribution, is reproduced below, and is
 
8
available at http://www.eclipse.org/org/documents/edl-v10.php
 
9
 
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or
 
13
without modification, are permitted provided that the following
 
14
conditions are met:
 
15
 
 
16
- Redistributions of source code must retain the above copyright
 
17
  notice, this list of conditions and the following disclaimer.
 
18
 
 
19
- Redistributions in binary form must reproduce the above
 
20
  copyright notice, this list of conditions and the following
 
21
  disclaimer in the documentation and/or other materials provided
 
22
  with the distribution.
 
23
 
 
24
- Neither the name of the Eclipse Foundation, Inc. nor the
 
25
  names of its contributors may be used to endorse or promote
 
26
  products derived from this software without specific prior
 
27
  written permission.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 
30
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
31
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
32
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
33
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
34
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
35
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
36
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
37
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
38
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
39
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
42
*/
 
43
 
 
44
using System;
 
45
using System.Collections.Generic;
 
46
using System.IO;
 
47
using NGit;
 
48
using NGit.Internal;
 
49
using NGit.Junit;
 
50
using NGit.Merge;
 
51
using NGit.Revwalk;
 
52
using NGit.Storage.File;
 
53
using NGit.Util;
 
54
using Sharpen;
 
55
 
 
56
namespace NGit.Storage.File
 
57
{
 
58
        [NUnit.Framework.TestFixture]
 
59
        public class GCTest : LocalDiskRepositoryTestCase
 
60
        {
 
61
                private TestRepository<FileRepository> tr;
 
62
 
 
63
                private FileRepository repo;
 
64
 
 
65
                private GC gc;
 
66
 
 
67
                private GC.RepoStatistics stats;
 
68
 
 
69
                /// <exception cref="System.Exception"></exception>
 
70
                [NUnit.Framework.SetUp]
 
71
                public override void SetUp()
 
72
                {
 
73
                        base.SetUp();
 
74
                        repo = CreateWorkRepository();
 
75
                        tr = new TestRepository<FileRepository>((repo));
 
76
                        gc = new GC(repo);
 
77
                }
 
78
 
 
79
                /// <exception cref="System.Exception"></exception>
 
80
                [NUnit.Framework.TearDown]
 
81
                public override void TearDown()
 
82
                {
 
83
                        base.TearDown();
 
84
                }
 
85
 
 
86
                // GC.packRefs tests
 
87
                /// <exception cref="System.Exception"></exception>
 
88
                [NUnit.Framework.Test]
 
89
                public virtual void PackRefs_looseRefPacked()
 
90
                {
 
91
                        RevBlob a = tr.Blob("a");
 
92
                        tr.LightweightTag("t", a);
 
93
                        gc.PackRefs();
 
94
                        NUnit.Framework.Assert.AreEqual(repo.GetRef("t").GetStorage(), RefStorage.PACKED);
 
95
                }
 
96
 
 
97
                /// <exception cref="System.Exception"></exception>
 
98
                [NUnit.Framework.Test]
 
99
                public virtual void ConcurrentPackRefs_onlyOneWritesPackedRefs()
 
100
                {
 
101
                        RevBlob a = tr.Blob("a");
 
102
                        tr.LightweightTag("t", a);
 
103
                        CyclicBarrier syncPoint = new CyclicBarrier(2);
 
104
                        Callable<int> packRefs = new _Callable_131(this, syncPoint);
 
105
                        ExecutorService pool = Executors.NewFixedThreadPool(2);
 
106
                        try
 
107
                        {
 
108
                                Future<int> p1 = pool.Submit(packRefs);
 
109
                                Future<int> p2 = pool.Submit(packRefs);
 
110
                                NUnit.Framework.Assert.AreEqual(1, p1.Get() + p2.Get());
 
111
                        }
 
112
                        finally
 
113
                        {
 
114
                                pool.Shutdown();
 
115
                                pool.AwaitTermination(long.MaxValue, TimeUnit.SECONDS);
 
116
                        }
 
117
                }
 
118
 
 
119
                private sealed class _Callable_131 : Callable<int>
 
120
                {
 
121
                        public _Callable_131(GCTest _enclosing, CyclicBarrier syncPoint)
 
122
                        {
 
123
                                this._enclosing = _enclosing;
 
124
                                this.syncPoint = syncPoint;
 
125
                        }
 
126
 
 
127
                        /// <returns>0 for success, 1 in case of error when writing pack</returns>
 
128
                        /// <exception cref="System.Exception"></exception>
 
129
                        public int Call()
 
130
                        {
 
131
                                syncPoint.Await();
 
132
                                try
 
133
                                {
 
134
                                        this._enclosing.gc.PackRefs();
 
135
                                        return Sharpen.Extensions.ValueOf(0);
 
136
                                }
 
137
                                catch (IOException)
 
138
                                {
 
139
                                        return Sharpen.Extensions.ValueOf(1);
 
140
                                }
 
141
                        }
 
142
 
 
143
                        private readonly GCTest _enclosing;
 
144
 
 
145
                        private readonly CyclicBarrier syncPoint;
 
146
                }
 
147
 
 
148
                /// <exception cref="System.Exception"></exception>
 
149
                [NUnit.Framework.Test]
 
150
                public virtual void PackRefsWhileRefLocked_refNotPackedNoError()
 
151
                {
 
152
                        RevBlob a = tr.Blob("a");
 
153
                        tr.LightweightTag("t1", a);
 
154
                        tr.LightweightTag("t2", a);
 
155
                        LockFile refLock = new LockFile(new FilePath(repo.Directory, "refs/tags/t1"), repo
 
156
                                .FileSystem);
 
157
                        try
 
158
                        {
 
159
                                refLock.Lock();
 
160
                                gc.PackRefs();
 
161
                        }
 
162
                        finally
 
163
                        {
 
164
                                refLock.Unlock();
 
165
                        }
 
166
                        NUnit.Framework.Assert.AreEqual(repo.GetRef("refs/tags/t1").GetStorage(), RefStorage
 
167
                                .LOOSE);
 
168
                        NUnit.Framework.Assert.AreEqual(repo.GetRef("refs/tags/t2").GetStorage(), RefStorage
 
169
                                .PACKED);
 
170
                }
 
171
 
 
172
                /// <exception cref="System.Exception"></exception>
 
173
                [NUnit.Framework.Test]
 
174
                public virtual void PackRefsWhileRefUpdated_refUpdateSucceeds()
 
175
                {
 
176
                        RevBlob a = tr.Blob("a");
 
177
                        tr.LightweightTag("t", a);
 
178
                        RevBlob b = tr.Blob("b");
 
179
                        CyclicBarrier refUpdateLockedRef = new CyclicBarrier(2);
 
180
                        CyclicBarrier packRefsDone = new CyclicBarrier(2);
 
181
                        ExecutorService pool = Executors.NewFixedThreadPool(2);
 
182
                        try
 
183
                        {
 
184
                                Future<RefUpdate.Result> result = pool.Submit(new _Callable_185(this, b, refUpdateLockedRef
 
185
                                        , packRefsDone));
 
186
                                pool.Submit<object>(new _Callable_210(this, refUpdateLockedRef, packRefsDone));
 
187
                                NUnit.Framework.Assert.AreEqual(result.Get(), RefUpdate.Result.FORCED);
 
188
                        }
 
189
                        finally
 
190
                        {
 
191
                                pool.ShutdownNow();
 
192
                                pool.AwaitTermination(long.MaxValue, TimeUnit.SECONDS);
 
193
                        }
 
194
                        NUnit.Framework.Assert.AreEqual(repo.GetRef("refs/tags/t").GetObjectId(), b);
 
195
                }
 
196
 
 
197
                private sealed class _Callable_185 : Callable<RefUpdate.Result>
 
198
                {
 
199
                        public _Callable_185(GCTest _enclosing, RevBlob b, CyclicBarrier refUpdateLockedRef
 
200
                                , CyclicBarrier packRefsDone)
 
201
                        {
 
202
                                this._enclosing = _enclosing;
 
203
                                this.b = b;
 
204
                                this.refUpdateLockedRef = refUpdateLockedRef;
 
205
                                this.packRefsDone = packRefsDone;
 
206
                        }
 
207
 
 
208
                        /// <exception cref="System.Exception"></exception>
 
209
                        public RefUpdate.Result Call()
 
210
                        {
 
211
                                RefUpdate update = new _RefDirectoryUpdate_190(refUpdateLockedRef, packRefsDone, 
 
212
                                        (RefDirectory)this._enclosing.repo.RefDatabase, this._enclosing.repo.GetRef("refs/tags/t"
 
213
                                        ));
 
214
                                update.SetForceUpdate(true);
 
215
                                update.SetNewObjectId(b);
 
216
                                return update.Update();
 
217
                        }
 
218
 
 
219
                        private sealed class _RefDirectoryUpdate_190 : RefDirectoryUpdate
 
220
                        {
 
221
                                public _RefDirectoryUpdate_190(CyclicBarrier refUpdateLockedRef, CyclicBarrier packRefsDone
 
222
                                        , RefDirectory baseArg1, Ref baseArg2) : base(baseArg1, baseArg2)
 
223
                                {
 
224
                                        this.refUpdateLockedRef = refUpdateLockedRef;
 
225
                                        this.packRefsDone = packRefsDone;
 
226
                                }
 
227
 
 
228
                                public override bool IsForceUpdate()
 
229
                                {
 
230
                                        try
 
231
                                        {
 
232
                                                refUpdateLockedRef.Await();
 
233
                                                packRefsDone.Await();
 
234
                                        }
 
235
                                        catch (Exception)
 
236
                                        {
 
237
                                                Sharpen.Thread.CurrentThread().Interrupt();
 
238
                                        }
 
239
                                        return base.IsForceUpdate();
 
240
                                }
 
241
 
 
242
                                private readonly CyclicBarrier refUpdateLockedRef;
 
243
 
 
244
                                private readonly CyclicBarrier packRefsDone;
 
245
                        }
 
246
 
 
247
                        private readonly GCTest _enclosing;
 
248
 
 
249
                        private readonly RevBlob b;
 
250
 
 
251
                        private readonly CyclicBarrier refUpdateLockedRef;
 
252
 
 
253
                        private readonly CyclicBarrier packRefsDone;
 
254
                }
 
255
 
 
256
                private sealed class _Callable_210 : Callable<object>
 
257
                {
 
258
                        public _Callable_210(GCTest _enclosing, CyclicBarrier refUpdateLockedRef, CyclicBarrier
 
259
                                 packRefsDone)
 
260
                        {
 
261
                                this._enclosing = _enclosing;
 
262
                                this.refUpdateLockedRef = refUpdateLockedRef;
 
263
                                this.packRefsDone = packRefsDone;
 
264
                        }
 
265
 
 
266
                        /// <exception cref="System.Exception"></exception>
 
267
                        public object Call()
 
268
                        {
 
269
                                refUpdateLockedRef.Await();
 
270
                                this._enclosing.gc.PackRefs();
 
271
                                packRefsDone.Await();
 
272
                                return null;
 
273
                        }
 
274
 
 
275
                        private readonly GCTest _enclosing;
 
276
 
 
277
                        private readonly CyclicBarrier refUpdateLockedRef;
 
278
 
 
279
                        private readonly CyclicBarrier packRefsDone;
 
280
                }
 
281
 
 
282
                // GC.repack tests
 
283
                /// <exception cref="System.IO.IOException"></exception>
 
284
                [NUnit.Framework.Test]
 
285
                public virtual void RepackEmptyRepo_noPackCreated()
 
286
                {
 
287
                        gc.Repack();
 
288
                        NUnit.Framework.Assert.AreEqual(0, ((ObjectDirectory)repo.ObjectDatabase).GetPacks
 
289
                                ().Count);
 
290
                }
 
291
 
 
292
                /// <exception cref="System.Exception"></exception>
 
293
                [NUnit.Framework.Test]
 
294
                public virtual void ConcurrentRepack()
 
295
                {
 
296
                        //
 
297
                        // leave the syncPoint in broken state so any awaiting
 
298
                        // threads and any threads that call await in the future get
 
299
                        // the BrokenBarrierException
 
300
                        //
 
301
                        CyclicBarrier syncPoint = new CyclicBarrier(1);
 
302
                        RevBlob a = tr.Blob("a");
 
303
                        tr.LightweightTag("t", a);
 
304
                        ExecutorService pool = Executors.NewFixedThreadPool(2);
 
305
                        try
 
306
                        {
 
307
                                _T187790690 repack1 = new _T187790690(this) { syncPoint = syncPoint };
 
308
                                //_T187790690 repack2 = new _T187790690(this) { syncPoint = syncPoint };
 
309
                                Future<int> result1 = pool.Submit(repack1);
 
310
                                //Future<int> result2 = pool.Submit(repack2);
 
311
                                NUnit.Framework.Assert.AreEqual(0, result1.Get());// + result2.Get());
 
312
                        }
 
313
                        finally
 
314
                        {
 
315
                                pool.Shutdown();
 
316
                                pool.AwaitTermination(long.MaxValue, TimeUnit.SECONDS);
 
317
                        }
 
318
                }
 
319
 
 
320
                internal class _T187790690 : EmptyProgressMonitor, Callable<int>
 
321
                {
 
322
                        public CyclicBarrier syncPoint;
 
323
                        public override void BeginTask(string title, int totalWork)
 
324
                        {
 
325
                                if (title.Equals(JGitText.Get().writingObjects))
 
326
                                {
 
327
                                        try
 
328
                                        {
 
329
                                                syncPoint.Await();
 
330
                                        }
 
331
                                        catch (Exception)
 
332
                                        {
 
333
                                                Sharpen.Thread.CurrentThread().Interrupt();
 
334
                                        }
 
335
                                }
 
336
                        }
 
337
 
 
338
                        /// <returns>0 for success, 1 in case of error when writing pack</returns>
 
339
                        /// <exception cref="System.Exception"></exception>
 
340
                        public virtual int Call()
 
341
                        {
 
342
                                try
 
343
                                {
 
344
                                        this._enclosing.gc.SetProgressMonitor(this);
 
345
                                        this._enclosing.gc.Repack();
 
346
                                        return Sharpen.Extensions.ValueOf(0);
 
347
                                }
 
348
                                catch (IOException)
 
349
                                {
 
350
                                        Sharpen.Thread.CurrentThread().Interrupt();
 
351
                                        try
 
352
                                        {
 
353
                                                syncPoint.Await();
 
354
                                        }
 
355
                                        catch (Exception)
 
356
                                        {
 
357
                                        }
 
358
                                        return Sharpen.Extensions.ValueOf(1);
 
359
                                }
 
360
                        }
 
361
 
 
362
                        internal _T187790690(GCTest _enclosing)
 
363
                        {
 
364
                                this._enclosing = _enclosing;
 
365
                        }
 
366
 
 
367
                        private readonly GCTest _enclosing;
 
368
                }
 
369
 
 
370
                // GC.prune tests
 
371
                /// <exception cref="System.Exception"></exception>
 
372
                [NUnit.Framework.Test]
 
373
                public virtual void NonReferencedNonExpiredObject_notPruned()
 
374
                {
 
375
                        RevBlob a = tr.Blob("a");
 
376
                        gc.SetExpire(Sharpen.Extensions.CreateDate(LastModified(a)));
 
377
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
378
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(a));
 
379
                }
 
380
 
 
381
                /// <exception cref="System.Exception"></exception>
 
382
                [NUnit.Framework.Test]
 
383
                public virtual void NonReferencedExpiredObject_pruned()
 
384
                {
 
385
                        RevBlob a = tr.Blob("a");
 
386
                        gc.SetExpireAgeMillis(0);
 
387
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
388
                        NUnit.Framework.Assert.IsFalse(repo.HasObject(a));
 
389
                }
 
390
 
 
391
                /// <exception cref="System.Exception"></exception>
 
392
                [NUnit.Framework.Test]
 
393
                public virtual void NonReferencedExpiredObjectTree_pruned()
 
394
                {
 
395
                        RevBlob a = tr.Blob("a");
 
396
                        RevTree t = tr.Tree(tr.File("a", a));
 
397
                        gc.SetExpireAgeMillis(0);
 
398
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
399
                        NUnit.Framework.Assert.IsFalse(repo.HasObject(t));
 
400
                        NUnit.Framework.Assert.IsFalse(repo.HasObject(a));
 
401
                }
 
402
 
 
403
                /// <exception cref="System.Exception"></exception>
 
404
                [NUnit.Framework.Test]
 
405
                public virtual void NonReferencedObjects_onlyExpiredPruned()
 
406
                {
 
407
                        RevBlob a = tr.Blob("a");
 
408
                        gc.SetExpire(Sharpen.Extensions.CreateDate(LastModified(a) + 1));
 
409
                        FsTick();
 
410
                        RevBlob b = tr.Blob("b");
 
411
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
412
                        NUnit.Framework.Assert.IsFalse(repo.HasObject(a));
 
413
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(b));
 
414
                }
 
415
 
 
416
                /// <exception cref="System.Exception"></exception>
 
417
                [NUnit.Framework.Test]
 
418
                public virtual void LightweightTag_objectNotPruned()
 
419
                {
 
420
                        RevBlob a = tr.Blob("a");
 
421
                        tr.LightweightTag("t", a);
 
422
                        gc.SetExpireAgeMillis(0);
 
423
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
424
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(a));
 
425
                }
 
426
 
 
427
                /// <exception cref="System.Exception"></exception>
 
428
                [NUnit.Framework.Test]
 
429
                public virtual void AnnotatedTag_objectNotPruned()
 
430
                {
 
431
                        RevBlob a = tr.Blob("a");
 
432
                        RevTag t = tr.Tag("t", a);
 
433
                        // this doesn't create the refs/tags/t ref
 
434
                        tr.LightweightTag("t", t);
 
435
                        gc.SetExpireAgeMillis(0);
 
436
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
437
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(t));
 
438
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(a));
 
439
                }
 
440
 
 
441
                /// <exception cref="System.Exception"></exception>
 
442
                [NUnit.Framework.Test]
 
443
                public virtual void Branch_historyNotPruned()
 
444
                {
 
445
                        RevCommit tip = CommitChain(10);
 
446
                        tr.Branch("b").Update(tip);
 
447
                        gc.SetExpireAgeMillis(0);
 
448
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
449
                        do
 
450
                        {
 
451
                                NUnit.Framework.Assert.IsTrue(repo.HasObject(tip));
 
452
                                tr.ParseBody(tip);
 
453
                                RevTree t = tip.Tree;
 
454
                                NUnit.Framework.Assert.IsTrue(repo.HasObject(t));
 
455
                                NUnit.Framework.Assert.IsTrue(repo.HasObject(tr.Get(t, "a")));
 
456
                                tip = tip.ParentCount > 0 ? tip.GetParent(0) : null;
 
457
                        }
 
458
                        while (tip != null);
 
459
                }
 
460
 
 
461
                /// <exception cref="System.Exception"></exception>
 
462
                [NUnit.Framework.Test]
 
463
                public virtual void DeleteBranch_historyPruned()
 
464
                {
 
465
                        RevCommit tip = CommitChain(10);
 
466
                        tr.Branch("b").Update(tip);
 
467
                        RefUpdate update = repo.UpdateRef("refs/heads/b");
 
468
                        update.SetForceUpdate(true);
 
469
                        update.Delete();
 
470
                        gc.SetExpireAgeMillis(0);
 
471
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
472
                        NUnit.Framework.Assert.IsTrue(gc.GetStatistics().numberOfLooseObjects == 0);
 
473
                }
 
474
 
 
475
                /// <exception cref="System.Exception"></exception>
 
476
                [NUnit.Framework.Test]
 
477
                public virtual void DeleteMergedBranch_historyNotPruned()
 
478
                {
 
479
                        RevCommit parent = tr.Commit().Create();
 
480
                        RevCommit b1Tip = tr.Branch("b1").Commit().Parent(parent).Add("x", "x").Create();
 
481
                        RevCommit b2Tip = tr.Branch("b2").Commit().Parent(parent).Add("y", "y").Create();
 
482
                        // merge b1Tip and b2Tip and update refs/heads/b1 to the merge commit
 
483
                        Merger merger = ((ThreeWayMerger)MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.NewMerger(repo
 
484
                                ));
 
485
                        merger.Merge(b1Tip, b2Tip);
 
486
                        NGit.Junit.CommitBuilder cb = tr.Commit();
 
487
                        cb.Parent(b1Tip).Parent(b2Tip);
 
488
                        cb.SetTopLevelTree(merger.GetResultTreeId());
 
489
                        RevCommit mergeCommit = cb.Create();
 
490
                        RefUpdate u = repo.UpdateRef("refs/heads/b1");
 
491
                        u.SetNewObjectId(mergeCommit);
 
492
                        u.Update();
 
493
                        RefUpdate update = repo.UpdateRef("refs/heads/b2");
 
494
                        update.SetForceUpdate(true);
 
495
                        update.Delete();
 
496
                        gc.SetExpireAgeMillis(0);
 
497
                        gc.Prune(Collections.EmptySet<ObjectId>());
 
498
                        NUnit.Framework.Assert.IsTrue(repo.HasObject(b2Tip));
 
499
                }
 
500
 
 
501
                /// <exception cref="System.Exception"></exception>
 
502
                [NUnit.Framework.Test]
 
503
                public virtual void TestPackAllObjectsInOnePack()
 
504
                {
 
505
                        tr.Branch("refs/heads/master").Commit().Add("A", "A").Add("B", "B").Create();
 
506
                        stats = gc.GetStatistics();
 
507
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
508
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
509
                        gc.Gc();
 
510
                        stats = gc.GetStatistics();
 
511
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
512
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
 
513
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
514
                }
 
515
 
 
516
                /// <exception cref="System.Exception"></exception>
 
517
                [NUnit.Framework.Test]
 
518
                public virtual void TestKeepFiles()
 
519
                {
 
520
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
521
                        bb.Commit().Add("A", "A").Add("B", "B").Create();
 
522
                        stats = gc.GetStatistics();
 
523
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
524
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
525
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackFiles);
 
526
                        gc.Gc();
 
527
                        stats = gc.GetStatistics();
 
528
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
529
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
 
530
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
531
                        Iterator<PackFile> packIt = ((ObjectDirectory)repo.ObjectDatabase).GetPacks().Iterator
 
532
                                ();
 
533
                        PackFile singlePack = packIt.Next();
 
534
                        NUnit.Framework.Assert.IsFalse(packIt.HasNext());
 
535
                        FilePath keepFile = new FilePath(singlePack.GetPackFile().GetPath() + ".keep");
 
536
                        NUnit.Framework.Assert.IsFalse(keepFile.Exists());
 
537
                        NUnit.Framework.Assert.IsTrue(keepFile.CreateNewFile());
 
538
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
539
                        stats = gc.GetStatistics();
 
540
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
541
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
 
542
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
543
                        gc.Gc();
 
544
                        stats = gc.GetStatistics();
 
545
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
546
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
547
                        NUnit.Framework.Assert.AreEqual(2, stats.numberOfPackFiles);
 
548
                        // check that no object is packed twice
 
549
                        Iterator<PackFile> packs = ((ObjectDirectory)repo.ObjectDatabase).GetPacks().Iterator
 
550
                                ();
 
551
                        PackIndex ind1 = packs.Next().GetIndex();
 
552
                        NUnit.Framework.Assert.AreEqual(4, ind1.GetObjectCount());
 
553
                        PackIndex ind2 = packs.Next().GetIndex();
 
554
                        NUnit.Framework.Assert.AreEqual(4, ind2.GetObjectCount());
 
555
                        foreach (PackIndex.MutableEntry e in ind1)
 
556
                        {
 
557
                                if (ind2.HasObject(e.ToObjectId()))
 
558
                                {
 
559
                                        NUnit.Framework.Assert.IsFalse(ind2.HasObject(e.ToObjectId()), "the following object is in both packfiles: "
 
560
                                                 + e.ToObjectId());
 
561
                                }
 
562
                        }
 
563
                }
 
564
 
 
565
                /// <exception cref="System.Exception"></exception>
 
566
                [NUnit.Framework.Test]
 
567
                public virtual void TestPackRepoWithNoRefs()
 
568
                {
 
569
                        tr.Commit().Add("A", "A").Add("B", "B").Create();
 
570
                        stats = gc.GetStatistics();
 
571
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
572
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
573
                        gc.Gc();
 
574
                        stats = gc.GetStatistics();
 
575
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
576
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
577
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackFiles);
 
578
                }
 
579
 
 
580
                /// <exception cref="System.Exception"></exception>
 
581
                [NUnit.Framework.Test]
 
582
                public virtual void TestPack2Commits()
 
583
                {
 
584
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
585
                        bb.Commit().Add("A", "A").Add("B", "B").Create();
 
586
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
587
                        stats = gc.GetStatistics();
 
588
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
589
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
590
                        gc.Gc();
 
591
                        stats = gc.GetStatistics();
 
592
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
593
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
594
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
595
                }
 
596
 
 
597
                /// <exception cref="System.Exception"></exception>
 
598
                [NUnit.Framework.Test]
 
599
                public virtual void TestPackCommitsAndLooseOne()
 
600
                {
 
601
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
602
                        RevCommit first = bb.Commit().Add("A", "A").Add("B", "B").Create();
 
603
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
604
                        tr.Update("refs/heads/master", first);
 
605
                        stats = gc.GetStatistics();
 
606
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
607
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
608
                        gc.Gc();
 
609
                        stats = gc.GetStatistics();
 
610
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
611
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
612
                        NUnit.Framework.Assert.AreEqual(2, stats.numberOfPackFiles);
 
613
                }
 
614
 
 
615
                /// <exception cref="System.Exception"></exception>
 
616
                [NUnit.Framework.Test]
 
617
                public virtual void TestNotPackTwice()
 
618
                {
 
619
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
620
                        RevCommit first = bb.Commit().Message("M").Add("M", "M").Create();
 
621
                        bb.Commit().Message("B").Add("B", "Q").Create();
 
622
                        bb.Commit().Message("A").Add("A", "A").Create();
 
623
                        RevCommit second = tr.Commit().Parent(first).Message("R").Add("R", "Q").Create();
 
624
                        tr.Update("refs/tags/t1", second);
 
625
                        ICollection<PackFile> oldPacks = ((ObjectDirectory)tr.GetRepository().ObjectDatabase
 
626
                                ).GetPacks();
 
627
                        NUnit.Framework.Assert.AreEqual(0, oldPacks.Count);
 
628
                        stats = gc.GetStatistics();
 
629
                        NUnit.Framework.Assert.AreEqual(11, stats.numberOfLooseObjects);
 
630
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
631
                        gc.SetExpireAgeMillis(0);
 
632
                        gc.Gc();
 
633
                        stats = gc.GetStatistics();
 
634
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
635
                        Iterator<PackFile> pIt = ((ObjectDirectory)repo.ObjectDatabase).GetPacks().Iterator
 
636
                                ();
 
637
                        long c = pIt.Next().GetObjectCount();
 
638
                        if (c == 9)
 
639
                        {
 
640
                                NUnit.Framework.Assert.AreEqual(2, pIt.Next().GetObjectCount());
 
641
                        }
 
642
                        else
 
643
                        {
 
644
                                NUnit.Framework.Assert.AreEqual(2, c);
 
645
                                NUnit.Framework.Assert.AreEqual(9, pIt.Next().GetObjectCount());
 
646
                        }
 
647
                }
 
648
 
 
649
                /// <exception cref="System.Exception"></exception>
 
650
                [NUnit.Framework.Test]
 
651
                public virtual void TestPackCommitsAndLooseOneNoReflog()
 
652
                {
 
653
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
654
                        RevCommit first = bb.Commit().Add("A", "A").Add("B", "B").Create();
 
655
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
656
                        tr.Update("refs/heads/master", first);
 
657
                        stats = gc.GetStatistics();
 
658
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
659
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
660
                        FileUtils.Delete(new FilePath(repo.Directory, "logs/HEAD"), FileUtils.RETRY | FileUtils
 
661
                                .SKIP_MISSING);
 
662
                        FileUtils.Delete(new FilePath(repo.Directory, "logs/refs/heads/master"), FileUtils
 
663
                                .RETRY | FileUtils.SKIP_MISSING);
 
664
                        gc.Gc();
 
665
                        stats = gc.GetStatistics();
 
666
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfLooseObjects);
 
667
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
 
668
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
669
                }
 
670
 
 
671
                /// <exception cref="System.Exception"></exception>
 
672
                [NUnit.Framework.Test]
 
673
                public virtual void TestPackCommitsAndLooseOneWithPruneNow()
 
674
                {
 
675
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
676
                        RevCommit first = bb.Commit().Add("A", "A").Add("B", "B").Create();
 
677
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
678
                        tr.Update("refs/heads/master", first);
 
679
                        stats = gc.GetStatistics();
 
680
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
681
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
682
                        gc.SetExpireAgeMillis(0);
 
683
                        gc.Gc();
 
684
                        stats = gc.GetStatistics();
 
685
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
686
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
687
                        NUnit.Framework.Assert.AreEqual(2, stats.numberOfPackFiles);
 
688
                }
 
689
 
 
690
                /// <exception cref="System.Exception"></exception>
 
691
                [NUnit.Framework.Test]
 
692
                public virtual void TestPackCommitsAndLooseOneWithPruneNowNoReflog()
 
693
                {
 
694
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
695
                        RevCommit first = bb.Commit().Add("A", "A").Add("B", "B").Create();
 
696
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
697
                        tr.Update("refs/heads/master", first);
 
698
                        stats = gc.GetStatistics();
 
699
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
700
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
701
                        FileUtils.Delete(new FilePath(repo.Directory, "logs/HEAD"), FileUtils.RETRY | FileUtils
 
702
                                .SKIP_MISSING);
 
703
                        FileUtils.Delete(new FilePath(repo.Directory, "logs/refs/heads/master"), FileUtils
 
704
                                .RETRY | FileUtils.SKIP_MISSING);
 
705
                        gc.SetExpireAgeMillis(0);
 
706
                        gc.Gc();
 
707
                        stats = gc.GetStatistics();
 
708
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
709
                        NUnit.Framework.Assert.AreEqual(4, stats.numberOfPackedObjects);
 
710
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
711
                }
 
712
 
 
713
                /// <exception cref="System.Exception"></exception>
 
714
                [NUnit.Framework.Test]
 
715
                public virtual void TestIndexSavesObjects()
 
716
                {
 
717
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
718
                        bb.Commit().Add("A", "A").Add("B", "B").Create();
 
719
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
720
                        bb.Commit().Add("A", "A3");
 
721
                        // this new content in index should survive
 
722
                        stats = gc.GetStatistics();
 
723
                        NUnit.Framework.Assert.AreEqual(9, stats.numberOfLooseObjects);
 
724
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
725
                        gc.Gc();
 
726
                        stats = gc.GetStatistics();
 
727
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfLooseObjects);
 
728
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
729
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
730
                }
 
731
 
 
732
                /// <exception cref="System.Exception"></exception>
 
733
                [NUnit.Framework.Test]
 
734
                public virtual void TestIndexSavesObjectsWithPruneNow()
 
735
                {
 
736
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
737
                        bb.Commit().Add("A", "A").Add("B", "B").Create();
 
738
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
739
                        bb.Commit().Add("A", "A3");
 
740
                        // this new content in index should survive
 
741
                        stats = gc.GetStatistics();
 
742
                        NUnit.Framework.Assert.AreEqual(9, stats.numberOfLooseObjects);
 
743
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfPackedObjects);
 
744
                        gc.SetExpireAgeMillis(0);
 
745
                        gc.Gc();
 
746
                        stats = gc.GetStatistics();
 
747
                        NUnit.Framework.Assert.AreEqual(0, stats.numberOfLooseObjects);
 
748
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfPackedObjects);
 
749
                        NUnit.Framework.Assert.AreEqual(1, stats.numberOfPackFiles);
 
750
                }
 
751
 
 
752
                /// <exception cref="System.Exception"></exception>
 
753
                [NUnit.Framework.Test]
 
754
                public virtual void TestPruneNone()
 
755
                {
 
756
                        BranchBuilder bb = tr.Branch("refs/heads/master");
 
757
                        bb.Commit().Add("A", "A").Add("B", "B").Create();
 
758
                        bb.Commit().Add("A", "A2").Add("B", "B2").Create();
 
759
                        new FilePath(repo.Directory, Constants.LOGS + "/refs/heads/master").Delete();
 
760
                        stats = gc.GetStatistics();
 
761
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
762
                        gc.SetExpireAgeMillis(0);
 
763
                        gc.Prune(Sharpen.Collections.EmptySet<ObjectId>());
 
764
                        stats = gc.GetStatistics();
 
765
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
766
                        tr.Blob("x");
 
767
                        stats = gc.GetStatistics();
 
768
                        NUnit.Framework.Assert.AreEqual(9, stats.numberOfLooseObjects);
 
769
                        gc.Prune(Sharpen.Collections.EmptySet<ObjectId>());
 
770
                        stats = gc.GetStatistics();
 
771
                        NUnit.Framework.Assert.AreEqual(8, stats.numberOfLooseObjects);
 
772
                }
 
773
 
 
774
                /// <summary>Create a chain of commits of given depth.</summary>
 
775
                /// <remarks>
 
776
                /// Create a chain of commits of given depth.
 
777
                /// <p>
 
778
                /// Each commit contains one file named "a" containing the index of the
 
779
                /// commit in the chain as its content. The created commit chain is
 
780
                /// referenced from any ref.
 
781
                /// <p>
 
782
                /// A chain of depth = N will create 3*N objects in Gits object database. For
 
783
                /// each depth level three objects are created: the commit object, the
 
784
                /// top-level tree object and a blob for the content of the file "a".
 
785
                /// </remarks>
 
786
                /// <param name="depth">the depth of the commit chain.</param>
 
787
                /// <returns>the commit that is the tip of the commit chain</returns>
 
788
                /// <exception cref="System.Exception">System.Exception</exception>
 
789
                private RevCommit CommitChain(int depth)
 
790
                {
 
791
                        if (depth <= 0)
 
792
                        {
 
793
                                throw new ArgumentException("Chain depth must be > 0");
 
794
                        }
 
795
                        NGit.Junit.CommitBuilder cb = tr.Commit();
 
796
                        RevCommit tip;
 
797
                        do
 
798
                        {
 
799
                                --depth;
 
800
                                tip = cb.Add("a", string.Empty + depth).Message(string.Empty + depth).Create();
 
801
                                cb = cb.Child();
 
802
                        }
 
803
                        while (depth > 0);
 
804
                        return tip;
 
805
                }
 
806
 
 
807
                private long LastModified(AnyObjectId objectId)
 
808
                {
 
809
                        return ((ObjectDirectory)repo.ObjectDatabase).FileFor(objectId).LastModified();
 
810
                }
 
811
 
 
812
                /// <exception cref="System.Exception"></exception>
 
813
                /// <exception cref="System.IO.IOException"></exception>
 
814
                private static void FsTick()
 
815
                {
 
816
                        RepositoryTestCase.FsTick(null);
 
817
                }
 
818
        }
 
819
}