Skip to content

Commit 4e5a841

Browse files
authored
Merge pull request #28 from pjbgf/fix-go-git-data-race
Fix data race when running `go-git` tests
2 parents 7ab80d7 + 38b02ce commit 4e5a841

File tree

7 files changed

+75
-44
lines changed

7 files changed

+75
-44
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
on: [push, pull_request]
22
name: Test
3+
permissions: {}
34
jobs:
45
test:
56
strategy:
67
matrix:
7-
go-version: [1.14.x, 1.15.x, 1.16.x]
8+
go-version: [1.18.x,1.19.x]
89
platform: [ubuntu-latest, macos-latest, windows-latest]
910
runs-on: ${{ matrix.platform }}
1011
steps:
1112
- name: Install Go
12-
uses: actions/setup-go@v1
13+
uses: actions/setup-go@v3
1314
with:
1415
go-version: ${{ matrix.go-version }}
1516
- name: Checkout code
16-
uses: actions/checkout@v2
17+
uses: actions/checkout@v3
1718
- name: Test
18-
run: go test ./...
19+
run: make test

.github/workflows/test_js.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
on: [push, pull_request]
2-
name: Test
2+
name: Test JS
3+
permissions: {}
34
jobs:
45
test:
56
strategy:
67
matrix:
7-
go-version: [1.14.x, 1.15.x, 1.16.x]
8+
go-version: [1.18.x,1.19.x]
89
runs-on: ubuntu-latest
910
steps:
1011
- name: Install Go
11-
uses: actions/setup-go@v1
12+
uses: actions/setup-go@v3
1213
with:
1314
go-version: ${{ matrix.go-version }}
1415

1516
- name: Install wasmbrowsertest
1617
run: |
17-
go get github.com/agnivade/wasmbrowsertest
18+
go install github.com/agnivade/wasmbrowsertest@latest
1819
mv $HOME/go/bin/wasmbrowsertest $HOME/go/bin/go_js_wasm_exec
1920
2021
- name: Checkout code
21-
uses: actions/checkout@v2
22+
uses: actions/checkout@v3
2223

2324
- name: Test
2425
run: go test -exec="$HOME/go/bin/go_js_wasm_exec" ./...

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Go parameters
2+
GOCMD = go
3+
GOTEST = $(GOCMD) test
4+
5+
.PHONY: test
6+
test:
7+
$(GOTEST) -race ./...
8+
9+
test-coverage:
10+
echo "" > $(COVERAGE_REPORT); \
11+
$(GOTEST) -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... -covermode=$(COVERAGE_MODE) ./...

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ module github.com/go-git/go-billy/v5
33
require (
44
github.com/kr/text v0.2.0 // indirect
55
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
6-
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
7-
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f
6+
golang.org/x/sys v0.3.0
7+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
88
)
99

1010
go 1.13

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
22
github.com/go-git/go-billy v1.0.0 h1:bXR6Zu3opPSg0R4dDxqaLglY4rxw7ja7wS16qSpOKL4=
33
github.com/go-git/go-billy v3.1.0+incompatible h1:dwrJ8G2Jt1srYgIJs+lRjA36qBY68O2Lg5idKG8ef5M=
4+
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
5+
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
46
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
57
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
68
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -10,5 +12,11 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
1012
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
1113
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
1214
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
15+
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
16+
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
17+
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
18+
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1319
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
1420
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
21+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
22+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

memfs/storage.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"os"
88
"path/filepath"
9+
"sync"
910
)
1011

1112
type storage struct {
@@ -174,6 +175,8 @@ func clean(path string) string {
174175
type content struct {
175176
name string
176177
bytes []byte
178+
179+
m sync.RWMutex
177180
}
178181

179182
func (c *content) WriteAt(p []byte, off int64) (int, error) {
@@ -185,6 +188,7 @@ func (c *content) WriteAt(p []byte, off int64) (int, error) {
185188
}
186189
}
187190

191+
c.m.Lock()
188192
prev := len(c.bytes)
189193

190194
diff := int(off) - prev
@@ -196,6 +200,7 @@ func (c *content) WriteAt(p []byte, off int64) (int, error) {
196200
if len(c.bytes) < prev {
197201
c.bytes = c.bytes[:prev]
198202
}
203+
c.m.Unlock()
199204

200205
return len(p), nil
201206
}
@@ -209,8 +214,10 @@ func (c *content) ReadAt(b []byte, off int64) (n int, err error) {
209214
}
210215
}
211216

217+
c.m.RLock()
212218
size := int64(len(c.bytes))
213219
if off >= size {
220+
c.m.RUnlock()
214221
return 0, io.EOF
215222
}
216223

@@ -220,10 +227,12 @@ func (c *content) ReadAt(b []byte, off int64) (n int, err error) {
220227
}
221228

222229
btr := c.bytes[off : off+l]
230+
n = copy(b, btr)
231+
223232
if len(btr) < len(b) {
224233
err = io.EOF
225234
}
226-
n = copy(b, btr)
235+
c.m.RUnlock()
227236

228237
return
229238
}

util/walk_test.go

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type WalkSuite struct{}
2020
func TestWalk(t *testing.T) { TestingT(t) }
2121

2222
var _ = Suite(&WalkSuite{})
23+
var targetSubfolder = filepath.FromSlash("path/to/some/subfolder")
2324

2425
func (s *WalkSuite) TestWalkCanSkipTopDirectory(c *C) {
2526
filesystem := memfs.New()
@@ -52,13 +53,13 @@ func (s *WalkSuite) TestWalkOnExistingFolder(c *C) {
5253
return nil
5354
}), IsNil)
5455
c.Assert(discoveredPaths, Contains, "path")
55-
c.Assert(discoveredPaths, Contains, "path/to")
56-
c.Assert(discoveredPaths, Contains, "path/to/some")
57-
c.Assert(discoveredPaths, Contains, "path/to/some/file")
58-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder")
59-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder/that")
60-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder/that/contain")
61-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder/that/contain/file")
56+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
57+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
58+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
59+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
60+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that"))
61+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that/contain"))
62+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
6263
}
6364

6465
func (s *WalkSuite) TestWalkCanSkipFolder(c *C) {
@@ -68,19 +69,19 @@ func (s *WalkSuite) TestWalkCanSkipFolder(c *C) {
6869
discoveredPaths := []string{}
6970
c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
7071
discoveredPaths = append(discoveredPaths, path)
71-
if path == "path/to/some/subfolder" {
72+
if path == targetSubfolder {
7273
return filepath.SkipDir
7374
}
7475
return nil
7576
}), IsNil)
7677
c.Assert(discoveredPaths, Contains, "path")
77-
c.Assert(discoveredPaths, Contains, "path/to")
78-
c.Assert(discoveredPaths, Contains, "path/to/some")
79-
c.Assert(discoveredPaths, Contains, "path/to/some/file")
80-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder")
81-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that")
82-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain")
83-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain/file")
78+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
79+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
80+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
81+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
82+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
83+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
84+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
8485
}
8586

8687
func (s *WalkSuite) TestWalkStopsOnError(c *C) {
@@ -90,27 +91,27 @@ func (s *WalkSuite) TestWalkStopsOnError(c *C) {
9091
discoveredPaths := []string{}
9192
c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
9293
discoveredPaths = append(discoveredPaths, path)
93-
if path == "path/to/some/subfolder" {
94+
if path == targetSubfolder {
9495
return errors.New("uncaught error")
9596
}
9697
return nil
9798
}), NotNil)
9899
c.Assert(discoveredPaths, Contains, "path")
99-
c.Assert(discoveredPaths, Contains, "path/to")
100-
c.Assert(discoveredPaths, Contains, "path/to/some")
101-
c.Assert(discoveredPaths, Contains, "path/to/some/file")
102-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder")
103-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that")
104-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain")
105-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain/file")
100+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
101+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
102+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
103+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
104+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
105+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
106+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
106107
}
107108

108109
func (s *WalkSuite) TestWalkForwardsStatErrors(c *C) {
109110
memFilesystem := memfs.New()
110111
filesystem := &fnFs{
111112
Filesystem: memFilesystem,
112113
lstat: func(path string) (os.FileInfo, error) {
113-
if path == "path/to/some/subfolder" {
114+
if path == targetSubfolder {
114115
return nil, errors.New("uncaught error")
115116
}
116117
return memFilesystem.Lstat(path)
@@ -122,19 +123,19 @@ func (s *WalkSuite) TestWalkForwardsStatErrors(c *C) {
122123
discoveredPaths := []string{}
123124
c.Assert(util.Walk(filesystem, "path", func(path string, info os.FileInfo, err error) error {
124125
discoveredPaths = append(discoveredPaths, path)
125-
if path == "path/to/some/subfolder" {
126+
if path == targetSubfolder {
126127
c.Assert(err, NotNil)
127128
}
128129
return err
129130
}), NotNil)
130131
c.Assert(discoveredPaths, Contains, "path")
131-
c.Assert(discoveredPaths, Contains, "path/to")
132-
c.Assert(discoveredPaths, Contains, "path/to/some")
133-
c.Assert(discoveredPaths, Contains, "path/to/some/file")
134-
c.Assert(discoveredPaths, Contains, "path/to/some/subfolder")
135-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that")
136-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain")
137-
c.Assert(discoveredPaths, NotContain, "path/to/some/subfolder/that/contain/file")
132+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to"))
133+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some"))
134+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/file"))
135+
c.Assert(discoveredPaths, Contains, filepath.FromSlash("path/to/some/subfolder"))
136+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that"))
137+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain"))
138+
c.Assert(discoveredPaths, NotContain, filepath.FromSlash("path/to/some/subfolder/that/contain/file"))
138139
}
139140

140141
func createFile(c *C, filesystem billy.Filesystem, path string) {

0 commit comments

Comments
 (0)