[ARVADOS] created: 05f572e397a8a1d0cdadc4f1d75e800098503cb8
git at public.curoverse.com
git at public.curoverse.com
Wed Dec 2 18:07:45 EST 2015
at 05f572e397a8a1d0cdadc4f1d75e800098503cb8 (commit)
commit 05f572e397a8a1d0cdadc4f1d75e800098503cb8
Author: Tom Clegg <tom at curoverse.com>
Date: Wed Dec 2 18:17:48 2015 -0500
7393: Add boilerplate for S3 volume type and tests.
diff --git a/services/keepstore/azure_blob_volume.go b/services/keepstore/azure_blob_volume.go
index e9fda2a..0f98e6e 100644
--- a/services/keepstore/azure_blob_volume.go
+++ b/services/keepstore/azure_blob_volume.go
@@ -189,7 +189,7 @@ func (v *AzureBlobVolume) Compare(loc string, expect []byte) error {
return compareReaderWithBuf(rdr, expect, loc[:32])
}
-// Put sotres a Keep block as a block blob in the container.
+// Put stores a Keep block as a block blob in the container.
func (v *AzureBlobVolume) Put(loc string, block []byte) error {
if v.readonly {
return MethodDisabledError
diff --git a/services/keepstore/azure_blob_volume_test.go b/services/keepstore/azure_blob_volume_test.go
index a240c23..b8bf5cb 100644
--- a/services/keepstore/azure_blob_volume_test.go
+++ b/services/keepstore/azure_blob_volume_test.go
@@ -292,10 +292,10 @@ type TestableAzureBlobVolume struct {
*AzureBlobVolume
azHandler *azStubHandler
azStub *httptest.Server
- t *testing.T
+ t TB
}
-func NewTestableAzureBlobVolume(t *testing.T, readonly bool, replication int) *TestableAzureBlobVolume {
+func NewTestableAzureBlobVolume(t TB, readonly bool, replication int) *TestableAzureBlobVolume {
azHandler := newAzStubHandler()
azStub := httptest.NewServer(azHandler)
@@ -341,7 +341,7 @@ func TestAzureBlobVolumeWithGeneric(t *testing.T) {
}
azureWriteRaceInterval = time.Millisecond
azureWriteRacePollTime = time.Nanosecond
- DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+ DoGenericVolumeTests(t, func(t TB) TestableVolume {
return NewTestableAzureBlobVolume(t, false, azureStorageReplication)
})
}
@@ -355,7 +355,7 @@ func TestReadonlyAzureBlobVolumeWithGeneric(t *testing.T) {
}
azureWriteRaceInterval = time.Millisecond
azureWriteRacePollTime = time.Nanosecond
- DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+ DoGenericVolumeTests(t, func(t TB) TestableVolume {
return NewTestableAzureBlobVolume(t, true, azureStorageReplication)
})
}
diff --git a/services/keepstore/handlers_with_generic_volume_test.go b/services/keepstore/handlers_with_generic_volume_test.go
index 9f31f5f..c5349d3 100644
--- a/services/keepstore/handlers_with_generic_volume_test.go
+++ b/services/keepstore/handlers_with_generic_volume_test.go
@@ -2,19 +2,18 @@ package main
import (
"bytes"
- "testing"
)
// A TestableVolumeManagerFactory creates a volume manager with at least two TestableVolume instances.
// The factory function, and the TestableVolume instances it returns, can use "t" to write
// logs, fail the current test, etc.
-type TestableVolumeManagerFactory func(t *testing.T) (*RRVolumeManager, []TestableVolume)
+type TestableVolumeManagerFactory func(t TB) (*RRVolumeManager, []TestableVolume)
// DoHandlersWithGenericVolumeTests runs a set of handler tests with a
// Volume Manager comprised of TestableVolume instances.
// It calls factory to create a volume manager with TestableVolume
// instances for each test case, to avoid leaking state between tests.
-func DoHandlersWithGenericVolumeTests(t *testing.T, factory TestableVolumeManagerFactory) {
+func DoHandlersWithGenericVolumeTests(t TB, factory TestableVolumeManagerFactory) {
testGetBlock(t, factory, TestHash, TestBlock)
testGetBlock(t, factory, EmptyHash, EmptyBlock)
testPutRawBadDataGetBlock(t, factory, TestHash, TestBlock, []byte("baddata"))
@@ -26,7 +25,7 @@ func DoHandlersWithGenericVolumeTests(t *testing.T, factory TestableVolumeManage
}
// Setup RRVolumeManager with TestableVolumes
-func setupHandlersWithGenericVolumeTest(t *testing.T, factory TestableVolumeManagerFactory) []TestableVolume {
+func setupHandlersWithGenericVolumeTest(t TB, factory TestableVolumeManagerFactory) []TestableVolume {
vm, testableVolumes := factory(t)
KeepVM = vm
@@ -39,7 +38,7 @@ func setupHandlersWithGenericVolumeTest(t *testing.T, factory TestableVolumeMana
}
// Put a block using PutRaw in just one volume and Get it using GetBlock
-func testGetBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
+func testGetBlock(t TB, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
// Put testBlock in one volume
@@ -56,7 +55,7 @@ func testGetBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash s
}
// Put a bad block using PutRaw and get it.
-func testPutRawBadDataGetBlock(t *testing.T, factory TestableVolumeManagerFactory,
+func testPutRawBadDataGetBlock(t TB, factory TestableVolumeManagerFactory,
testHash string, testBlock []byte, badData []byte) {
testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
@@ -72,7 +71,7 @@ func testPutRawBadDataGetBlock(t *testing.T, factory TestableVolumeManagerFactor
}
// Invoke PutBlock twice to ensure CompareAndTouch path is tested.
-func testPutBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
+func testPutBlock(t TB, factory TestableVolumeManagerFactory, testHash string, testBlock []byte) {
setupHandlersWithGenericVolumeTest(t, factory)
// PutBlock
@@ -95,7 +94,7 @@ func testPutBlock(t *testing.T, factory TestableVolumeManagerFactory, testHash s
}
// Put a bad block using PutRaw, overwrite it using PutBlock and get it.
-func testPutBlockCorrupt(t *testing.T, factory TestableVolumeManagerFactory,
+func testPutBlockCorrupt(t TB, factory TestableVolumeManagerFactory,
testHash string, testBlock []byte, badData []byte) {
testableVolumes := setupHandlersWithGenericVolumeTest(t, factory)
diff --git a/services/keepstore/s3_volume.go b/services/keepstore/s3_volume.go
new file mode 100644
index 0000000..7dd22f4
--- /dev/null
+++ b/services/keepstore/s3_volume.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "io"
+ "regexp"
+ "time"
+
+ "gopkg.in/amz.v2/aws"
+ "gopkg.in/amz.v2/s3"
+)
+
+type S3Volume struct {
+ *s3.Bucket
+ readonly bool
+ replication int
+}
+
+// NewS3Volume returns a new S3Volume using the given client and
+// bucket name. The replication argument specifies the replication
+// level to report when writing data.
+func NewS3Volume(auth aws.Auth, region aws.Region, bucket string, readonly bool, replication int) *S3Volume {
+ return &S3Volume{
+ Bucket: &s3.Bucket{
+ S3: s3.New(auth, region),
+ Name: bucket,
+ },
+ readonly: readonly,
+ replication: replication,
+ }
+}
+
+func (v *S3Volume) Check() error {
+ return nil
+}
+
+func (v *S3Volume) Get(loc string) ([]byte, error) {
+ return nil, nil
+}
+
+func (v *S3Volume) get(loc string) ([]byte, error) {
+ return nil, nil
+}
+
+func (v *S3Volume) Compare(loc string, expect []byte) error {
+ return nil
+}
+
+func (v *S3Volume) Put(loc string, block []byte) error {
+ return nil
+}
+
+func (v *S3Volume) Touch(loc string) error {
+ return nil
+}
+
+func (v *S3Volume) Mtime(loc string) (time.Time, error) {
+ return time.Time{}, nil
+}
+
+func (v *S3Volume) IndexTo(prefix string, writer io.Writer) error {
+ return nil
+}
+
+func (v *S3Volume) Delete(loc string) error {
+ return nil
+}
+
+func (v *S3Volume) Status() *VolumeStatus {
+ return nil
+}
+
+func (v *S3Volume) String() string {
+ return ""
+}
+
+func (v *S3Volume) Writable() bool {
+ return !v.readonly
+}
+func (v *S3Volume) Replication() int {
+ return v.replication
+}
+var s3KeepBlockRegexp = regexp.MustCompile(`^[0-9a-f]{32}$`)
+func (v *S3Volume) isKeepBlock(s string) bool {
+ return s3KeepBlockRegexp.MatchString(s)
+}
diff --git a/services/keepstore/s3_volume_test.go b/services/keepstore/s3_volume_test.go
new file mode 100644
index 0000000..3cc4fd8
--- /dev/null
+++ b/services/keepstore/s3_volume_test.go
@@ -0,0 +1,94 @@
+package main
+
+import (
+ "fmt"
+ "time"
+
+ check "gopkg.in/check.v1"
+ "gopkg.in/amz.v2/aws"
+ "gopkg.in/amz.v2/s3"
+ "gopkg.in/amz.v2/s3/s3test"
+)
+
+type checker struct {
+ check.C
+ skipped bool
+}
+
+func (c checker) Skip(args ...interface{}) {
+ c.skipped = true
+ c.C.Skip(fmt.Sprintf("%v", args[0]))
+}
+
+func (c checker) Skipf(f string, args ...interface{}) {
+ c.skipped = true
+ c.C.Skip(fmt.Sprintf(f, args...))
+}
+
+func (c checker) SkipNow() {
+ c.skipped = true
+ c.C.Skip("")
+}
+
+func (c checker) Skipped() bool {
+ return c.skipped
+}
+
+type TestableS3Volume struct {
+ *S3Volume
+ server *s3test.Server
+ c *check.C
+}
+
+const (
+ TestBucketName = "testbucket"
+)
+
+func NewTestableS3Volume(c *check.C, readonly bool, replication int) *TestableS3Volume {
+ srv, err := s3test.NewServer(&s3test.Config{})
+ c.Assert(err, check.IsNil)
+ auth := aws.Auth{}
+ region := aws.Region{
+ S3Endpoint: srv.URL(),
+ }
+ bucket := &s3.Bucket{
+ S3: s3.New(auth, region),
+ Name: TestBucketName,
+ }
+ err = bucket.PutBucket(s3.ACL("private"))
+ c.Assert(err, check.IsNil)
+
+ return &TestableS3Volume{
+ S3Volume: NewS3Volume(auth, region, TestBucketName, readonly, replication),
+ server: srv,
+ }
+}
+
+var _ = check.Suite(&StubbedS3Suite{})
+
+type StubbedS3Suite struct {
+ volumes []*TestableS3Volume
+}
+
+func (s *StubbedS3Suite) SetUpTest(c *check.C) {
+ s.volumes = append(s.volumes[:0], NewTestableS3Volume(c, false, 2))
+}
+
+func (s *StubbedS3Suite) TestGeneric(c *check.C) {
+ DoGenericVolumeTests(&checker{C: *c}, func(t TB) TestableVolume {
+ return NewTestableS3Volume(c, false, 2)
+ })
+}
+
+func (v *TestableS3Volume) PutRaw(locator string, data []byte) {
+ // TODO
+}
+
+func (v *TestableS3Volume) TouchWithDate(locator string, lastPut time.Time) {
+ // TODO
+}
+
+func (v *TestableS3Volume) Teardown() {
+ // TODO
+}
+
diff --git a/services/keepstore/volume_generic_test.go b/services/keepstore/volume_generic_test.go
index 61088f1..cc3eb5a 100644
--- a/services/keepstore/volume_generic_test.go
+++ b/services/keepstore/volume_generic_test.go
@@ -8,19 +8,34 @@ import (
"regexp"
"sort"
"strings"
- "testing"
"time"
)
+type TB interface {
+ Error(args ...interface{})
+ Errorf(format string, args ...interface{})
+ Fail()
+ FailNow()
+ Failed() bool
+ Fatal(args ...interface{})
+ Fatalf(format string, args ...interface{})
+ Log(args ...interface{})
+ Logf(format string, args ...interface{})
+ Skip(args ...interface{})
+ SkipNow()
+ Skipf(format string, args ...interface{})
+ Skipped() bool
+}
+
// A TestableVolumeFactory returns a new TestableVolume. The factory
// function, and the TestableVolume it returns, can use "t" to write
// logs, fail the current test, etc.
-type TestableVolumeFactory func(t *testing.T) TestableVolume
+type TestableVolumeFactory func(t TB) TestableVolume
// DoGenericVolumeTests runs a set of tests that every TestableVolume
// is expected to pass. It calls factory to create a new TestableVolume
// for each test case, to avoid leaking state between tests.
-func DoGenericVolumeTests(t *testing.T, factory TestableVolumeFactory) {
+func DoGenericVolumeTests(t TB, factory TestableVolumeFactory) {
testGet(t, factory)
testGetNoSuchBlock(t, factory)
@@ -67,7 +82,7 @@ func DoGenericVolumeTests(t *testing.T, factory TestableVolumeFactory) {
// Put a test block, get it and verify content
// Test should pass for both writable and read-only volumes
-func testGet(t *testing.T, factory TestableVolumeFactory) {
+func testGet(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -87,7 +102,7 @@ func testGet(t *testing.T, factory TestableVolumeFactory) {
// Invoke get on a block that does not exist in volume; should result in error
// Test should pass for both writable and read-only volumes
-func testGetNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
+func testGetNoSuchBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -99,7 +114,7 @@ func testGetNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
// Compare() should return os.ErrNotExist if the block does not exist.
// Otherwise, writing new data causes CompareAndTouch() to generate
// error logs even though everything is working fine.
-func testCompareNonexistent(t *testing.T, factory TestableVolumeFactory) {
+func testCompareNonexistent(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -111,7 +126,7 @@ func testCompareNonexistent(t *testing.T, factory TestableVolumeFactory) {
// Put a test block and compare the locator with same content
// Test should pass for both writable and read-only volumes
-func testCompareSameContent(t *testing.T, factory TestableVolumeFactory, testHash string, testData []byte) {
+func testCompareSameContent(t TB, factory TestableVolumeFactory, testHash string, testData []byte) {
v := factory(t)
defer v.Teardown()
@@ -129,7 +144,7 @@ func testCompareSameContent(t *testing.T, factory TestableVolumeFactory, testHas
// testHash = md5(testDataA).
//
// Test should pass for both writable and read-only volumes
-func testCompareWithCollision(t *testing.T, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
+func testCompareWithCollision(t TB, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
v := factory(t)
defer v.Teardown()
@@ -146,7 +161,7 @@ func testCompareWithCollision(t *testing.T, factory TestableVolumeFactory, testH
// corrupted. Requires testHash = md5(testDataA) != md5(testDataB).
//
// Test should pass for both writable and read-only volumes
-func testCompareWithCorruptStoredData(t *testing.T, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
+func testCompareWithCorruptStoredData(t TB, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
v := factory(t)
defer v.Teardown()
@@ -160,7 +175,7 @@ func testCompareWithCorruptStoredData(t *testing.T, factory TestableVolumeFactor
// Put a block and put again with same content
// Test is intended for only writable volumes
-func testPutBlockWithSameContent(t *testing.T, factory TestableVolumeFactory, testHash string, testData []byte) {
+func testPutBlockWithSameContent(t TB, factory TestableVolumeFactory, testHash string, testData []byte) {
v := factory(t)
defer v.Teardown()
@@ -181,7 +196,7 @@ func testPutBlockWithSameContent(t *testing.T, factory TestableVolumeFactory, te
// Put a block and put again with different content
// Test is intended for only writable volumes
-func testPutBlockWithDifferentContent(t *testing.T, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
+func testPutBlockWithDifferentContent(t TB, factory TestableVolumeFactory, testHash string, testDataA, testDataB []byte) {
v := factory(t)
defer v.Teardown()
@@ -217,7 +232,7 @@ func testPutBlockWithDifferentContent(t *testing.T, factory TestableVolumeFactor
// Put and get multiple blocks
// Test is intended for only writable volumes
-func testPutMultipleBlocks(t *testing.T, factory TestableVolumeFactory) {
+func testPutMultipleBlocks(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -275,7 +290,7 @@ func testPutMultipleBlocks(t *testing.T, factory TestableVolumeFactory) {
// Test that when applying PUT to a block that already exists,
// the block's modification time is updated.
// Test is intended for only writable volumes
-func testPutAndTouch(t *testing.T, factory TestableVolumeFactory) {
+func testPutAndTouch(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -317,7 +332,7 @@ func testPutAndTouch(t *testing.T, factory TestableVolumeFactory) {
// Touching a non-existing block should result in error.
// Test should pass for both writable and read-only volumes
-func testTouchNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
+func testTouchNoSuchBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -328,7 +343,7 @@ func testTouchNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
// Invoking Mtime on a non-existing block should result in error.
// Test should pass for both writable and read-only volumes
-func testMtimeNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
+func testMtimeNoSuchBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -342,7 +357,7 @@ func testMtimeNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
// * with a prefix
// * with no such prefix
// Test should pass for both writable and read-only volumes
-func testIndexTo(t *testing.T, factory TestableVolumeFactory) {
+func testIndexTo(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -399,7 +414,7 @@ func testIndexTo(t *testing.T, factory TestableVolumeFactory) {
// Calling Delete() for a block immediately after writing it (not old enough)
// should neither delete the data nor return an error.
// Test is intended for only writable volumes
-func testDeleteNewBlock(t *testing.T, factory TestableVolumeFactory) {
+func testDeleteNewBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
blobSignatureTTL = 300 * time.Second
@@ -427,7 +442,7 @@ func testDeleteNewBlock(t *testing.T, factory TestableVolumeFactory) {
// Calling Delete() for a block with a timestamp older than
// blobSignatureTTL seconds in the past should delete the data.
// Test is intended for only writable volumes
-func testDeleteOldBlock(t *testing.T, factory TestableVolumeFactory) {
+func testDeleteOldBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
blobSignatureTTL = 300 * time.Second
@@ -449,7 +464,7 @@ func testDeleteOldBlock(t *testing.T, factory TestableVolumeFactory) {
// Calling Delete() for a block that does not exist should result in error.
// Test should pass for both writable and read-only volumes
-func testDeleteNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
+func testDeleteNoSuchBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -460,7 +475,7 @@ func testDeleteNoSuchBlock(t *testing.T, factory TestableVolumeFactory) {
// Invoke Status and verify that VolumeStatus is returned
// Test should pass for both writable and read-only volumes
-func testStatus(t *testing.T, factory TestableVolumeFactory) {
+func testStatus(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -481,7 +496,7 @@ func testStatus(t *testing.T, factory TestableVolumeFactory) {
// Invoke String for the volume; expect non-empty result
// Test should pass for both writable and read-only volumes
-func testString(t *testing.T, factory TestableVolumeFactory) {
+func testString(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -492,7 +507,7 @@ func testString(t *testing.T, factory TestableVolumeFactory) {
// Putting, updating, touching, and deleting blocks from a read-only volume result in error.
// Test is intended for only read-only volumes
-func testUpdateReadOnly(t *testing.T, factory TestableVolumeFactory) {
+func testUpdateReadOnly(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -539,7 +554,7 @@ func testUpdateReadOnly(t *testing.T, factory TestableVolumeFactory) {
// Launch concurrent Gets
// Test should pass for both writable and read-only volumes
-func testGetConcurrent(t *testing.T, factory TestableVolumeFactory) {
+func testGetConcurrent(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -592,7 +607,7 @@ func testGetConcurrent(t *testing.T, factory TestableVolumeFactory) {
// Launch concurrent Puts
// Test is intended for only writable volumes
-func testPutConcurrent(t *testing.T, factory TestableVolumeFactory) {
+func testPutConcurrent(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
@@ -660,7 +675,7 @@ func testPutConcurrent(t *testing.T, factory TestableVolumeFactory) {
}
// Write and read back a full size block
-func testPutFullBlock(t *testing.T, factory TestableVolumeFactory) {
+func testPutFullBlock(t TB, factory TestableVolumeFactory) {
v := factory(t)
defer v.Teardown()
diff --git a/services/keepstore/volume_unix_test.go b/services/keepstore/volume_unix_test.go
index 924637f..b216810 100644
--- a/services/keepstore/volume_unix_test.go
+++ b/services/keepstore/volume_unix_test.go
@@ -16,10 +16,10 @@ import (
type TestableUnixVolume struct {
UnixVolume
- t *testing.T
+ t TB
}
-func NewTestableUnixVolume(t *testing.T, serialize bool, readonly bool) *TestableUnixVolume {
+func NewTestableUnixVolume(t TB, serialize bool, readonly bool) *TestableUnixVolume {
d, err := ioutil.TempDir("", "volume_test")
if err != nil {
t.Fatal(err)
@@ -66,28 +66,28 @@ func (v *TestableUnixVolume) Teardown() {
// serialize = false; readonly = false
func TestUnixVolumeWithGenericTests(t *testing.T) {
- DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+ DoGenericVolumeTests(t, func(t TB) TestableVolume {
return NewTestableUnixVolume(t, false, false)
})
}
// serialize = false; readonly = true
func TestUnixVolumeWithGenericTestsReadOnly(t *testing.T) {
- DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+ DoGenericVolumeTests(t, func(t TB) TestableVolume {
return NewTestableUnixVolume(t, false, true)
})
}
// serialize = true; readonly = false
func TestUnixVolumeWithGenericTestsSerialized(t *testing.T) {
- DoGenericVolumeTests(t, func(t *testing.T) TestableVolume {
+ DoGenericVolumeTests(t, func(t TB) TestableVolume {
return NewTestableUnixVolume(t, true, false)
})
}
// serialize = false; readonly = false
func TestUnixVolumeHandlersWithGenericVolumeTests(t *testing.T) {
- DoHandlersWithGenericVolumeTests(t, func(t *testing.T) (*RRVolumeManager, []TestableVolume) {
+ DoHandlersWithGenericVolumeTests(t, func(t TB) (*RRVolumeManager, []TestableVolume) {
vols := make([]Volume, 2)
testableUnixVols := make([]TestableVolume, 2)
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list