2960: Refactor keepstore into a streaming server.
[arvados.git] / services / keepstore / streamwriterat_test.go
diff --git a/services/keepstore/streamwriterat_test.go b/services/keepstore/streamwriterat_test.go
new file mode 100644 (file)
index 0000000..fe6837e
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+package keepstore
+
+import (
+       "bytes"
+       "sync"
+
+       . "gopkg.in/check.v1"
+)
+
+var _ = Suite(&streamWriterAtSuite{})
+
+type streamWriterAtSuite struct{}
+
+func (s *streamWriterAtSuite) TestPartSizes(c *C) {
+       for partsize := 1; partsize < 5; partsize++ {
+               for writesize := 1; writesize < 5; writesize++ {
+                       for datasize := 1; datasize < 100; datasize += 13 {
+                               for bufextra := 0; bufextra < 5; bufextra++ {
+                                       c.Logf("=== partsize %d writesize %d datasize %d bufextra %d", partsize, writesize, datasize, bufextra)
+                                       outbuf := bytes.NewBuffer(nil)
+                                       indata := make([]byte, datasize)
+                                       for i := range indata {
+                                               indata[i] = byte(i)
+                                       }
+                                       swa := newStreamWriterAt(outbuf, partsize, make([]byte, datasize+bufextra))
+                                       var wg sync.WaitGroup
+                                       for pos := 0; pos < datasize; pos += writesize {
+                                               pos := pos
+                                               wg.Add(1)
+                                               go func() {
+                                                       defer wg.Done()
+                                                       endpos := pos + writesize
+                                                       if endpos > datasize {
+                                                               endpos = datasize
+                                                       }
+                                                       swa.WriteAt(indata[pos:endpos], int64(pos))
+                                               }()
+                                       }
+                                       wg.Wait()
+                                       swa.Close()
+                                       c.Check(outbuf.Bytes(), DeepEquals, indata)
+                               }
+                       }
+               }
+       }
+}
+
+func (s *streamWriterAtSuite) TestOverflow(c *C) {
+       for offset := -1; offset < 2; offset++ {
+               buf := make([]byte, 50)
+               swa := newStreamWriterAt(bytes.NewBuffer(nil), 20, buf)
+               _, err := swa.WriteAt([]byte("foo"), int64(len(buf)+offset))
+               c.Check(err, NotNil)
+               err = swa.Close()
+               c.Check(err, IsNil)
+       }
+}
+
+func (s *streamWriterAtSuite) TestIncompleteWrite(c *C) {
+       for _, partsize := range []int{20, 25} {
+               for _, bufsize := range []int{50, 55, 60} {
+                       for offset := 0; offset < 3; offset++ {
+                               swa := newStreamWriterAt(bytes.NewBuffer(nil), partsize, make([]byte, bufsize))
+                               _, err := swa.WriteAt(make([]byte, 1), 49)
+                               c.Check(err, IsNil)
+                               _, err = swa.WriteAt(make([]byte, 46), int64(offset))
+                               c.Check(err, IsNil)
+                               err = swa.Close()
+                               c.Check(err, NotNil)
+                               c.Check(swa.WroteAt(), Equals, 47)
+                               if offset == 0 {
+                                       c.Check(swa.Wrote(), Equals, 40/partsize*partsize)
+                               } else {
+                                       c.Check(swa.Wrote(), Equals, 0)
+                               }
+                       }
+               }
+       }
+}