Skip to content

Commit 1d3e068

Browse files
authored
Merge pull request #217 from vmarkovtsev/master
External identities + Burndown fix
2 parents 7ef5c47 + 1995126 commit 1d3e068

File tree

3 files changed

+141
-31
lines changed

3 files changed

+141
-31
lines changed

internal/plumbing/identity/identity.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ type Detector struct {
2525

2626
const (
2727
// AuthorMissing is the internal author index which denotes any unmatched identities
28-
// (Detector.Consume()).
29-
AuthorMissing = (1 << 18) - 1
28+
// (Detector.Consume()). It may *not* be (1 << 18) - 1, see BurndownAnalysis.packPersonWithDay().
29+
AuthorMissing = (1 << 18) - 2
3030
// AuthorMissingName is the string name which corresponds to AuthorMissing.
3131
AuthorMissingName = "<unmatched>"
3232

leaves/burndown.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ const (
161161
DefaultBurndownGranularity = 30
162162
// authorSelf is the internal author index which is used in BurndownAnalysis.Finalize() to
163163
// format the author overwrites matrix.
164-
authorSelf = (1 << (32 - burndown.TreeMaxBinPower)) - 2
164+
authorSelf = identity.AuthorMissing - 1
165165
)
166166

167167
type sparseHistory = map[int]map[int]int64
@@ -1004,8 +1004,12 @@ func (analyser *BurndownAnalysis) packPersonWithDay(person int, day int) int {
10041004
}
10051005
result := day & burndown.TreeMergeMark
10061006
result |= person << burndown.TreeMaxBinPower
1007-
// This effectively means max (16383 - 1) days (>44 years) and (131072 - 2) devs.
1007+
// This effectively means max (16383 - 1) days (>44 years) and (262143 - 3) devs.
10081008
// One day less because burndown.TreeMergeMark = ((1 << 14) - 1) is a special day.
1009+
// Three devs less because:
1010+
// - math.MaxUint32 is the special rbtree value with day == TreeMergeMark (-1)
1011+
// - identity.AuthorMissing (-2)
1012+
// - authorSelf (-3)
10091013
return result
10101014
}
10111015

leaves/burndown_test.go

+133-27
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func TestBurndownConfigure(t *testing.T) {
7070
facts[ConfigBurndownHibernationDirectory] = "xxx"
7171
facts[identity.FactIdentityDetectorPeopleCount] = 5
7272
facts[identity.FactIdentityDetectorReversedPeopleDict] = bd.Requires()
73-
bd.Configure(facts)
73+
assert.Nil(t, bd.Configure(facts))
7474
assert.Equal(t, bd.Granularity, 100)
7575
assert.Equal(t, bd.Sampling, 200)
7676
assert.Equal(t, bd.TrackFiles, true)
@@ -82,10 +82,10 @@ func TestBurndownConfigure(t *testing.T) {
8282
assert.Equal(t, bd.reversedPeopleDict, bd.Requires())
8383
facts[ConfigBurndownTrackPeople] = false
8484
facts[identity.FactIdentityDetectorPeopleCount] = 50
85-
bd.Configure(facts)
85+
assert.Nil(t, bd.Configure(facts))
8686
assert.Equal(t, bd.PeopleNumber, 0)
8787
facts = map[string]interface{}{}
88-
bd.Configure(facts)
88+
assert.Nil(t, bd.Configure(facts))
8989
assert.Equal(t, bd.Granularity, 100)
9090
assert.Equal(t, bd.Sampling, 200)
9191
assert.Equal(t, bd.TrackFiles, true)
@@ -110,24 +110,24 @@ func TestBurndownRegistration(t *testing.T) {
110110
}
111111

112112
func TestBurndownInitialize(t *testing.T) {
113-
burndown := BurndownAnalysis{}
114-
burndown.Sampling = -10
115-
burndown.Granularity = DefaultBurndownGranularity
116-
burndown.HibernationThreshold = 10
117-
burndown.Initialize(test.Repository)
118-
assert.Equal(t, burndown.Sampling, DefaultBurndownGranularity)
119-
assert.Equal(t, burndown.Granularity, DefaultBurndownGranularity)
120-
assert.Equal(t, burndown.fileAllocator.HibernationThreshold, 10)
121-
burndown.Sampling = 0
122-
burndown.Granularity = DefaultBurndownGranularity - 1
123-
burndown.Initialize(test.Repository)
124-
assert.Equal(t, burndown.Sampling, DefaultBurndownGranularity-1)
125-
assert.Equal(t, burndown.Granularity, DefaultBurndownGranularity-1)
126-
burndown.Sampling = DefaultBurndownGranularity - 1
127-
burndown.Granularity = -10
128-
burndown.Initialize(test.Repository)
129-
assert.Equal(t, burndown.Sampling, DefaultBurndownGranularity-1)
130-
assert.Equal(t, burndown.Granularity, DefaultBurndownGranularity)
113+
bd := BurndownAnalysis{}
114+
bd.Sampling = -10
115+
bd.Granularity = DefaultBurndownGranularity
116+
bd.HibernationThreshold = 10
117+
assert.Nil(t, bd.Initialize(test.Repository))
118+
assert.Equal(t, bd.Sampling, DefaultBurndownGranularity)
119+
assert.Equal(t, bd.Granularity, DefaultBurndownGranularity)
120+
assert.Equal(t, bd.fileAllocator.HibernationThreshold, 10)
121+
bd.Sampling = 0
122+
bd.Granularity = DefaultBurndownGranularity - 1
123+
assert.Nil(t, bd.Initialize(test.Repository))
124+
assert.Equal(t, bd.Sampling, DefaultBurndownGranularity-1)
125+
assert.Equal(t, bd.Granularity, DefaultBurndownGranularity-1)
126+
bd.Sampling = DefaultBurndownGranularity - 1
127+
bd.Granularity = -10
128+
assert.Nil(t, bd.Initialize(test.Repository))
129+
assert.Equal(t, bd.Sampling, DefaultBurndownGranularity-1)
130+
assert.Equal(t, bd.Granularity, DefaultBurndownGranularity)
131131
}
132132

133133
func TestBurndownConsumeFinalize(t *testing.T) {
@@ -137,7 +137,7 @@ func TestBurndownConsumeFinalize(t *testing.T) {
137137
PeopleNumber: 2,
138138
TrackFiles: true,
139139
}
140-
bd.Initialize(test.Repository)
140+
assert.Nil(t, bd.Initialize(test.Repository))
141141
deps := map[string]interface{}{}
142142

143143
// stage 1
@@ -216,15 +216,15 @@ func TestBurndownConsumeFinalize(t *testing.T) {
216216
Granularity: 30,
217217
Sampling: 0,
218218
}
219-
bd2.Initialize(test.Repository)
219+
assert.Nil(t, bd2.Initialize(test.Repository))
220220
_, err = bd2.Consume(deps)
221221
assert.Nil(t, err)
222222
assert.Len(t, bd2.peopleHistories, 0)
223223
assert.Len(t, bd2.fileHistories, 0)
224224

225225
// check merge hashes
226226
burndown3 := BurndownAnalysis{}
227-
burndown3.Initialize(test.Repository)
227+
assert.Nil(t, burndown3.Initialize(test.Repository))
228228
deps[identity.DependencyAuthor] = 1
229229
deps[core.DependencyIsMerge] = true
230230
_, err = burndown3.Consume(deps)
@@ -354,6 +354,112 @@ func TestBurndownConsumeFinalize(t *testing.T) {
354354
}
355355
}
356356

357+
func TestBurndownConsumeMergeAuthorMissing(t *testing.T) {
358+
deps := map[string]interface{}{}
359+
deps[items.DependencyDay] = 0
360+
cache := map[plumbing.Hash]*items.CachedBlob{}
361+
AddHash(t, cache, "291286b4ac41952cbd1389fda66420ec03c1a9fe")
362+
AddHash(t, cache, "c29112dbd697ad9b401333b80c18a63951bc18d9")
363+
AddHash(t, cache, "baa64828831d174f40140e4b3cfa77d1e917a2c1")
364+
AddHash(t, cache, "dc248ba2b22048cc730c571a748e8ffcf7085ab9")
365+
deps[items.DependencyBlobCache] = cache
366+
changes := make(object.Changes, 3)
367+
treeFrom, _ := test.Repository.TreeObject(plumbing.NewHash(
368+
"a1eb2ea76eb7f9bfbde9b243861474421000eb96"))
369+
treeTo, _ := test.Repository.TreeObject(plumbing.NewHash(
370+
"994eac1cd07235bb9815e547a75c84265dea00f5"))
371+
changes[0] = &object.Change{From: object.ChangeEntry{
372+
Name: "analyser.go",
373+
Tree: treeFrom,
374+
TreeEntry: object.TreeEntry{
375+
Name: "analyser.go",
376+
Mode: 0100644,
377+
Hash: plumbing.NewHash("dc248ba2b22048cc730c571a748e8ffcf7085ab9"),
378+
},
379+
}, To: object.ChangeEntry{
380+
Name: "analyser.go",
381+
Tree: treeTo,
382+
TreeEntry: object.TreeEntry{
383+
Name: "analyser.go",
384+
Mode: 0100644,
385+
Hash: plumbing.NewHash("baa64828831d174f40140e4b3cfa77d1e917a2c1"),
386+
},
387+
}}
388+
changes[1] = &object.Change{From: object.ChangeEntry{}, To: object.ChangeEntry{
389+
Name: "cmd/hercules/main.go",
390+
Tree: treeTo,
391+
TreeEntry: object.TreeEntry{
392+
Name: "cmd/hercules/main.go",
393+
Mode: 0100644,
394+
Hash: plumbing.NewHash("c29112dbd697ad9b401333b80c18a63951bc18d9"),
395+
},
396+
},
397+
}
398+
changes[2] = &object.Change{From: object.ChangeEntry{}, To: object.ChangeEntry{
399+
Name: ".travis.yml",
400+
Tree: treeTo,
401+
TreeEntry: object.TreeEntry{
402+
Name: ".travis.yml",
403+
Mode: 0100644,
404+
Hash: plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"),
405+
},
406+
},
407+
}
408+
deps[items.DependencyTreeChanges] = changes
409+
fd := fixtures.FileDiff()
410+
filediff, err := fd.Consume(deps)
411+
assert.Nil(t, err)
412+
deps[items.DependencyFileDiff] = filediff[items.DependencyFileDiff]
413+
deps[core.DependencyCommit], _ = test.Repository.CommitObject(plumbing.NewHash(
414+
"cce947b98a050c6d356bc6ba95030254914027b1"))
415+
416+
// check that we survive merge + missing author
417+
bd := BurndownAnalysis{PeopleNumber: 1}
418+
assert.Nil(t, bd.Initialize(test.Repository))
419+
deps[identity.DependencyAuthor] = 0
420+
deps[core.DependencyIsMerge] = false
421+
_, err = bd.Consume(deps)
422+
assert.Nil(t, err)
423+
424+
AddHash(t, cache, "4cdb0d969cf976f76634d1f348da3a175c9b4501")
425+
treeFrom, _ = test.Repository.TreeObject(plumbing.NewHash(
426+
"994eac1cd07235bb9815e547a75c84265dea00f5"))
427+
treeTo, _ = test.Repository.TreeObject(plumbing.NewHash(
428+
"89f33a2320f6cd0bd3d16351cfc10bea7e3dce1a"))
429+
changes = object.Changes{
430+
&object.Change{
431+
From: object.ChangeEntry{
432+
Name: ".travis.yml",
433+
Tree: treeFrom,
434+
TreeEntry: object.TreeEntry{
435+
Name: ".travis.yml",
436+
Mode: 0100644,
437+
Hash: plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"),
438+
},
439+
}, To: object.ChangeEntry{
440+
Name: ".travis.yml",
441+
Tree: treeTo,
442+
TreeEntry: object.TreeEntry{
443+
Name: ".travis.yml",
444+
Mode: 0100644,
445+
Hash: plumbing.NewHash("4cdb0d969cf976f76634d1f348da3a175c9b4501"),
446+
},
447+
},
448+
},
449+
}
450+
deps[items.DependencyTreeChanges] = changes
451+
filediff, err = fd.Consume(deps)
452+
assert.Nil(t, err)
453+
deps[items.DependencyFileDiff] = filediff[items.DependencyFileDiff]
454+
deps[core.DependencyCommit], _ = test.Repository.CommitObject(plumbing.NewHash(
455+
"7ef5c47aa79a1b229e3227d9ffe2401dbcbeb22f"))
456+
deps[identity.DependencyAuthor] = identity.AuthorMissing
457+
deps[core.DependencyIsMerge] = true
458+
_, err = bd.Consume(deps)
459+
assert.Nil(t, err)
460+
assert.Equal(t, identity.AuthorMissing, bd.mergedAuthor)
461+
}
462+
357463
func bakeBurndownForSerialization(t *testing.T, firstAuthor, secondAuthor int) (
358464
BurndownResult, *BurndownAnalysis) {
359465
bd := BurndownAnalysis{
@@ -362,7 +468,7 @@ func bakeBurndownForSerialization(t *testing.T, firstAuthor, secondAuthor int) (
362468
PeopleNumber: 2,
363469
TrackFiles: true,
364470
}
365-
bd.Initialize(test.Repository)
471+
assert.Nil(t, bd.Initialize(test.Repository))
366472
deps := map[string]interface{}{}
367473
// stage 1
368474
deps[identity.DependencyAuthor] = firstAuthor
@@ -502,7 +608,7 @@ func TestBurndownSerialize(t *testing.T) {
502608
bd := &BurndownAnalysis{}
503609

504610
buffer := &bytes.Buffer{}
505-
bd.Serialize(out, false, buffer)
611+
assert.Nil(t, bd.Serialize(out, false, buffer))
506612
assert.Equal(t, buffer.String(), ` granularity: 30
507613
sampling: 30
508614
"project": |-
@@ -581,7 +687,7 @@ func TestBurndownSerializeAuthorMissing(t *testing.T) {
581687
bd := &BurndownAnalysis{}
582688

583689
buffer := &bytes.Buffer{}
584-
bd.Serialize(out, false, buffer)
690+
assert.Nil(t, bd.Serialize(out, false, buffer))
585691
assert.Equal(t, buffer.String(), ` granularity: 30
586692
sampling: 30
587693
"project": |-

0 commit comments

Comments
 (0)