Skip to content

Commit 506c19b

Browse files
authored
Merge pull request #257 from Random-Liu/fix-race-condition
Add golang 1.10 and fix a race condition.
2 parents d4046a4 + 38f225e commit 506c19b

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dist: trusty
44

55
go:
66
- 1.9.x
7+
- 1.10.x
78

89
go_import_path: github.com/kubernetes-incubator/cri-tools
910

pkg/validate/streaming.go

+30-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"net/http"
2424
"net/url"
2525
"os"
26+
"sync"
2627
"time"
2728

2829
"github.com/kubernetes-incubator/cri-tools/pkg/framework"
@@ -190,20 +191,42 @@ func createDefaultAttach(c internalapi.RuntimeService, containerID string) strin
190191
return resp.Url
191192
}
192193

194+
// safeBuffer is a goroutine safe bytes.Buffer
195+
type safeBuffer struct {
196+
mu sync.Mutex
197+
buffer bytes.Buffer
198+
}
199+
200+
// Write appends the contents of p to the buffer, growing the buffer as needed. It returns
201+
// the number of bytes written.
202+
func (s *safeBuffer) Write(p []byte) (n int, err error) {
203+
s.mu.Lock()
204+
defer s.mu.Unlock()
205+
return s.buffer.Write(p)
206+
}
207+
208+
// String returns the contents of the unread portion of the buffer
209+
// as a string. If the Buffer is a nil pointer, it returns "<nil>".
210+
func (s *safeBuffer) String() string {
211+
s.mu.Lock()
212+
defer s.mu.Unlock()
213+
return s.buffer.String()
214+
}
215+
193216
func checkAttach(c internalapi.RuntimeService, attachServerURL string) {
194-
localOut := &bytes.Buffer{}
217+
localOut := &safeBuffer{buffer: bytes.Buffer{}}
195218
localErr := &bytes.Buffer{}
196219
reader, writer := io.Pipe()
197-
var out string
198-
199220
go func() {
200221
defer GinkgoRecover()
222+
defer writer.Close()
201223
writer.Write([]byte("echo hello\n"))
202224
Eventually(func() string {
203-
out = localOut.String()
204-
return out
205-
}, time.Minute, time.Second).ShouldNot(BeEmpty())
206-
writer.Close()
225+
return localOut.String()
226+
}, time.Minute, time.Second).Should(Equal("hello\n"), "The stdout of attach should be hello")
227+
Consistently(func() string {
228+
return localOut.String()
229+
}, 3*time.Second, time.Second).Should(Equal("hello\n"), "The stdout of attach should not contain other things")
207230
}()
208231

209232
// Only http is supported now.
@@ -220,7 +243,6 @@ func checkAttach(c internalapi.RuntimeService, attachServerURL string) {
220243
})
221244
framework.ExpectNoError(err, "failed to open streamer for %q", attachServerURL)
222245

223-
Expect(out).To(Equal("hello\n"), "The stdout of exec should be hello")
224246
Expect(localErr.String()).To(BeEmpty(), "The stderr of attach should be empty")
225247
framework.Logf("Check attach url %q succeed", attachServerURL)
226248
}

0 commit comments

Comments
 (0)