Skip to content

Commit bbbd2b5

Browse files
jazanneffluk3
andauthored
[sc-112730] fix: out of range error while running extinctions on large diffs (#425)
Adds a test case to verify the fix. The test data is taken from sergi/go-diff#89 data.txt --------- Co-authored-by: Lucas Shadler <[email protected]>
1 parent 38b8388 commit bbbd2b5

File tree

8 files changed

+218274
-112
lines changed

8 files changed

+218274
-112
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ require (
4545
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4646
github.com/sagikazarmark/locafero v0.4.0 // indirect
4747
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
48-
github.com/sergi/go-diff v1.1.0 // indirect
48+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
4949
github.com/skeema/knownhosts v1.2.1 // indirect
5050
github.com/sourcegraph/conc v0.3.0 // indirect
5151
github.com/spf13/afero v1.11.0 // indirect

go.sum

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
198198
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
199199
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
200200
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
201-
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
202-
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
201+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
202+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
203203
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
204204
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
205205
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
@@ -539,7 +539,7 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
539539
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
540540
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
541541
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
542-
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
542+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
543543
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
544544
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
545545
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 92 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package git
22

33
import (
4+
"io"
45
"os"
56
"path/filepath"
67
"testing"
78
"time"
89

910
"github.com/go-git/go-git/v5"
1011
"github.com/go-git/go-git/v5/plumbing/object"
12+
"github.com/stretchr/testify/assert"
1113
"github.com/stretchr/testify/require"
1214

1315
"github.com/launchdarkly/ld-find-code-refs/v2/internal/ld"
@@ -17,10 +19,14 @@ import (
1719
)
1820

1921
const (
20-
repoDir = "testdata/repo"
21-
flag1 = "flag1"
22-
flag2 = "flag2"
23-
flag3 = "flag3"
22+
REPO_DIR = "testdata/repo"
23+
)
24+
25+
var (
26+
flag1 = "flag1"
27+
flag2 = "flag2"
28+
flag3 = "flag3"
29+
flag4 = "flag4" // in bigdiff.txt
2430
)
2531

2632
func TestMain(m *testing.M) {
@@ -29,9 +35,9 @@ func TestMain(m *testing.M) {
2935
}
3036

3137
func setupRepo(t *testing.T) *git.Repository {
32-
os.RemoveAll(repoDir)
33-
require.NoError(t, os.MkdirAll(repoDir, 0700))
34-
repo, err := git.PlainInit(repoDir, false)
38+
os.RemoveAll(REPO_DIR)
39+
require.NoError(t, os.MkdirAll(REPO_DIR, 0700))
40+
repo, err := git.PlainInit(REPO_DIR, false)
3541
require.NoError(t, err)
3642
return repo
3743
}
@@ -41,21 +47,10 @@ func TestFindExtinctions(t *testing.T) {
4147
repo := setupRepo(t)
4248

4349
// Create commit history
44-
flagFile, err := os.Create(filepath.Join(repoDir, "flag1.txt"))
45-
require.NoError(t, err)
46-
_, err = flagFile.WriteString(flag1)
47-
require.NoError(t, err)
48-
require.NoError(t, flagFile.Close())
49-
flagFile, err = os.Create(filepath.Join(repoDir, "flag2.txt"))
50-
require.NoError(t, err)
51-
_, err = flagFile.WriteString(flag2)
52-
require.NoError(t, err)
53-
require.NoError(t, flagFile.Close())
54-
flagFile, err = os.Create(filepath.Join(repoDir, "flag3.txt"))
55-
require.NoError(t, err)
56-
_, err = flagFile.WriteString(flag3)
57-
require.NoError(t, err)
58-
require.NoError(t, flagFile.Close())
50+
createRepoFile(t, "flag1.txt", &flag1)
51+
createRepoFile(t, "flag2.txt", &flag2)
52+
createRepoFile(t, "flag3.txt", &flag3)
53+
copyFile(t, "testdata/bigdiff.txt", repoPath("bigdiff.txt"))
5954

6055
wt, err := repo.Worktree()
6156
require.NoError(t, err)
@@ -65,49 +60,54 @@ func TestFindExtinctions(t *testing.T) {
6560
wt.Add("flag1.txt")
6661
wt.Add("flag2.txt")
6762
wt.Add("flag3.txt")
63+
wt.Add("bigdiff.txt")
6864
_, err = wt.Commit("add flags", &git.CommitOptions{All: true, Committer: &who, Author: &who})
6965
require.NoError(t, err)
7066

7167
// Test with a removed file
72-
err = os.Remove(filepath.Join(repoDir, "flag1.txt"))
73-
require.NoError(t, err)
68+
removeRepoFile(t, "flag1.txt")
7469

75-
who.When = who.When.Add(time.Minute)
70+
who, when2 := incrementCommitTime(who)
7671
message2 := "remove flag1"
7772
commit2, err := wt.Commit(message2, &git.CommitOptions{All: true, Committer: &who, Author: &who})
7873
require.NoError(t, err)
7974

8075
// Test with an updated (truncated) file
81-
flagFile, err = os.Create(filepath.Join(repoDir, "flag2.txt"))
82-
require.NoError(t, err)
83-
require.NoError(t, flagFile.Close())
76+
createRepoFile(t, "flag2.txt", nil)
8477

85-
who.When = who.When.Add(time.Minute)
78+
who, when3 := incrementCommitTime(who)
8679
message3 := "remove flag2"
8780
commit3, err := wt.Commit("remove flag2", &git.CommitOptions{All: true, Committer: &who, Author: &who})
8881
require.NoError(t, err)
8982

90-
err = os.Remove(filepath.Join(repoDir, "flag3.txt"))
91-
require.NoError(t, err)
83+
removeRepoFile(t, "flag3.txt")
9284

93-
who.When = who.When.Add(time.Minute)
85+
who, when4 := incrementCommitTime(who)
9486
message4 := "remove flag3"
9587
commit4, err := wt.Commit("remove flag3", &git.CommitOptions{All: true, Committer: &who, Author: &who})
9688
require.NoError(t, err)
9789

98-
c := Client{workspace: repoDir}
90+
// Test big diff
91+
removeRepoFile(t, "bigdiff.txt")
92+
93+
who, when5 := incrementCommitTime(who)
94+
message5 := "remove flag4 from bigdiff"
95+
commit5, err := wt.Commit(message5, &git.CommitOptions{All: true, Committer: &who, Author: &who})
96+
require.NoError(t, err)
97+
98+
c := Client{workspace: REPO_DIR}
9999
projKey := options.Project{
100100
Key: "default",
101101
}
102102
addProjKey := options.Project{
103103
Key: "otherProject",
104104
}
105105
projects := []options.Project{projKey, addProjKey}
106-
missingFlags := [][]string{{flag1, flag2}, {flag3}}
106+
missingFlags := [][]string{{flag1, flag2}, {flag3, flag4}}
107107
matcher := search.Matcher{
108108
Elements: []search.ElementMatcher{
109109
search.NewElementMatcher(projKey.Key, ``, ``, []string{flag1, flag2}, nil),
110-
search.NewElementMatcher(addProjKey.Key, ``, ``, []string{flag3}, nil),
110+
search.NewElementMatcher(addProjKey.Key, ``, ``, []string{flag3, flag4}, nil),
111111
},
112112
}
113113

@@ -122,25 +122,78 @@ func TestFindExtinctions(t *testing.T) {
122122
{
123123
Revision: commit3.String(),
124124
Message: message3,
125-
Time: who.When.Add(-time.Minute).Unix() * 1000,
125+
Time: when3.UnixMilli(),
126126
ProjKey: projKey.Key,
127127
FlagKey: flag2,
128128
},
129129
{
130130
Revision: commit2.String(),
131131
Message: message2,
132-
Time: who.When.Add(-time.Minute*2).Unix() * 1000,
132+
Time: when2.UnixMilli(),
133133
ProjKey: projKey.Key,
134134
FlagKey: flag1,
135135
},
136+
{
137+
Revision: commit5.String(),
138+
Message: message5,
139+
Time: when5.UnixMilli(),
140+
ProjKey: addProjKey.Key,
141+
FlagKey: flag4,
142+
},
136143
{
137144
Revision: commit4.String(),
138145
Message: message4,
139-
Time: who.When.Unix() * 1000,
146+
Time: when4.UnixMilli(),
140147
ProjKey: addProjKey.Key,
141148
FlagKey: flag3,
142149
},
143150
}
144-
require.Equal(t, expected, extinctions)
145151

152+
for i, e := range expected {
153+
assert.Equalf(t, e, extinctions[i], "exinction at element %d does not match", i)
154+
}
155+
}
156+
157+
// Helper functions
158+
159+
func copyFile(t *testing.T, src, dst string) {
160+
sourceFileStat, err := os.Stat(src)
161+
require.NoError(t, err)
162+
require.Truef(t, sourceFileStat.Mode().IsRegular(), "%s is not a regular file", src)
163+
164+
source, err := os.Open(src)
165+
require.NoError(t, err)
166+
defer source.Close()
167+
168+
destination, err := os.Create(dst)
169+
require.NoError(t, err)
170+
171+
defer destination.Close()
172+
_, err = io.Copy(destination, source)
173+
require.NoError(t, err)
174+
}
175+
176+
func createRepoFile(t *testing.T, path string, content *string) {
177+
flagFile, err := os.Create(repoPath(path))
178+
require.NoError(t, err)
179+
if content != nil {
180+
_, err = flagFile.WriteString(*content)
181+
require.NoError(t, err)
182+
}
183+
require.NoError(t, flagFile.Close())
184+
}
185+
186+
func removeRepoFile(t *testing.T, path string) {
187+
require.NoError(t, os.Remove(filepath.Join(REPO_DIR, path)))
188+
}
189+
190+
func repoPath(path string) string {
191+
return filepath.Join(REPO_DIR, path)
192+
}
193+
194+
func incrementCommitTime(who object.Signature) (object.Signature, time.Time) {
195+
t := who.When.Add(time.Minute)
196+
who.When = t
197+
198+
return who, t
146199
}

0 commit comments

Comments
 (0)