veyron/lib/modules: fix bug in queue rw implementation and add unit test.
Bug: I forgot to shift the buffer upon consuming data from it, so it kept
reading from the beginning.
Should fix http://go/vissues/430.
Change-Id: I4a8fce8f20e10484e271abd2a9e25c158c2bb33b
diff --git a/lib/modules/only_for_test.go b/lib/modules/only_for_test.go
new file mode 100644
index 0000000..8f3143a
--- /dev/null
+++ b/lib/modules/only_for_test.go
@@ -0,0 +1,8 @@
+package modules
+
+import "io"
+
+// NewRW exposes newRW for unit tests.
+func NewRW() io.ReadWriteCloser {
+ return newRW()
+}
diff --git a/lib/modules/queue_rw.go b/lib/modules/queue_rw.go
index 8dbba9f..b4c83e9 100644
--- a/lib/modules/queue_rw.go
+++ b/lib/modules/queue_rw.go
@@ -8,8 +8,6 @@
"veyron.io/veyron/veyron/runtimes/google/lib/upcqueue"
)
-// TODO(caprita): Write unit tests.
-
// queueRW implements a ReadWriteCloser backed by an unbounded in-memory
// producer-consumer queue.
type queueRW struct {
@@ -47,6 +45,7 @@
q.buf, q.buffered = b, len(b)
}
copied := copy(p, q.buf[:q.buffered])
+ q.buf = q.buf[copied:]
q.buffered -= copied
return copied, nil
}
diff --git a/lib/modules/queue_rw_test.go b/lib/modules/queue_rw_test.go
new file mode 100644
index 0000000..735c301
--- /dev/null
+++ b/lib/modules/queue_rw_test.go
@@ -0,0 +1,60 @@
+package modules_test
+
+import (
+ "bytes"
+ "io"
+ "testing"
+
+ "veyron.io/veyron/veyron/lib/modules"
+ "veyron.io/veyron/veyron/lib/testutil"
+)
+
+func init() {
+ if !modules.IsModulesProcess() {
+ testutil.Init()
+ }
+}
+func TestQueueRW(t *testing.T) {
+ q := modules.NewRW()
+ size := testutil.Rand.Intn(1000)
+ data := testutil.RandomBytes(size)
+ begin := 0
+ for {
+ end := begin + testutil.Rand.Intn(100) + 1
+ if end > len(data) {
+ end = len(data)
+ }
+ n, err := q.Write(data[begin:end])
+ if err != nil {
+ t.Fatalf("Write failed: %v", err)
+ }
+ begin = begin + n
+ if begin == len(data) {
+ break
+ }
+ }
+ // This marks EOF.
+ if _, err := q.Write([]byte{}); err != nil {
+ t.Fatalf("err %v", err)
+ }
+ readData := make([]byte, 0, size)
+ for {
+ buf := make([]byte, testutil.Rand.Intn(100)+1)
+ n, err := q.Read(buf)
+ if n > 0 {
+ readData = append(readData, buf[:n]...)
+ }
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ t.Fatalf("Read failed: %v", err)
+ }
+ }
+ if size != len(readData) {
+ t.Fatalf("Mismatching data size: %d != %d", size, len(readData))
+ }
+ if !bytes.Equal(data, readData) {
+ t.Fatalf("Diffing data:\n%v\n%v", data, readData)
+ }
+}