forked from TrueCloudLab/distribution
Merge pull request #837 from BrianBland/ng-storagedriver-tests
Various storagedriver test additions/improvements
This commit is contained in:
commit
0317f17c41
2 changed files with 123 additions and 42 deletions
|
@ -90,8 +90,7 @@ func TestPush(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMap{
|
handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMapping{
|
||||||
{
|
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "PUT",
|
Method: "PUT",
|
||||||
Route: "/v2/" + name + "/manifest/" + tag,
|
Route: "/v2/" + name + "/manifest/" + tag,
|
||||||
|
@ -100,8 +99,7 @@ func TestPush(t *testing.T) {
|
||||||
Response: testutil.Response{
|
Response: testutil.Response{
|
||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
},
|
},
|
||||||
},
|
}))
|
||||||
}...))
|
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := New(server.URL)
|
client := New(server.URL)
|
||||||
objectStore := &memoryObjectStore{
|
objectStore := &memoryObjectStore{
|
||||||
|
@ -183,8 +181,7 @@ func TestPull(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMap{
|
handler := testutil.NewHandler(append(blobRequestResponseMappings, testutil.RequestResponseMapping{
|
||||||
{
|
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Route: "/v2/" + name + "/manifest/" + tag,
|
Route: "/v2/" + name + "/manifest/" + tag,
|
||||||
|
@ -193,8 +190,7 @@ func TestPull(t *testing.T) {
|
||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
Body: manifestBytes,
|
Body: manifestBytes,
|
||||||
},
|
},
|
||||||
},
|
}))
|
||||||
}...))
|
|
||||||
server := httptest.NewServer(handler)
|
server := httptest.NewServer(handler)
|
||||||
client := New(server.URL)
|
client := New(server.URL)
|
||||||
objectStore := &memoryObjectStore{
|
objectStore := &memoryObjectStore{
|
||||||
|
@ -306,8 +302,7 @@ func TestPullResume(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
layerRequestResponseMappings = append(layerRequestResponseMappings, testutil.RequestResponseMap{
|
layerRequestResponseMappings = append(layerRequestResponseMappings, testutil.RequestResponseMapping{
|
||||||
{
|
|
||||||
Request: testutil.Request{
|
Request: testutil.Request{
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
Route: "/v2/" + name + "/manifest/" + tag,
|
Route: "/v2/" + name + "/manifest/" + tag,
|
||||||
|
@ -316,8 +311,7 @@ func TestPullResume(t *testing.T) {
|
||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
Body: manifestBytes,
|
Body: manifestBytes,
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
}...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := testutil.NewHandler(layerRequestResponseMappings)
|
handler := testutil.NewHandler(layerRequestResponseMappings)
|
||||||
|
|
|
@ -396,9 +396,14 @@ func (suite *DriverSuite) TestContinueStreamAppend(c *check.C) {
|
||||||
// fails.
|
// fails.
|
||||||
func (suite *DriverSuite) TestReadNonexistentStream(c *check.C) {
|
func (suite *DriverSuite) TestReadNonexistentStream(c *check.C) {
|
||||||
filename := randomPath(32)
|
filename := randomPath(32)
|
||||||
|
|
||||||
_, err := suite.StorageDriver.ReadStream(filename, 0)
|
_, err := suite.StorageDriver.ReadStream(filename, 0)
|
||||||
c.Assert(err, check.NotNil)
|
c.Assert(err, check.NotNil)
|
||||||
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
|
|
||||||
|
_, err = suite.StorageDriver.ReadStream(filename, 64)
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestList checks the returned list of keys after populating a directory tree.
|
// TestList checks the returned list of keys after populating a directory tree.
|
||||||
|
@ -461,14 +466,54 @@ func (suite *DriverSuite) TestMove(c *check.C) {
|
||||||
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestMoveNonexistent checks that moving a nonexistent key fails
|
// TestMoveOverwrite checks that a moved object no longer exists at the source
|
||||||
|
// path and overwrites the contents at the destination.
|
||||||
|
func (suite *DriverSuite) TestMoveOverwrite(c *check.C) {
|
||||||
|
sourcePath := randomPath(32)
|
||||||
|
destPath := randomPath(32)
|
||||||
|
sourceContents := randomContents(32)
|
||||||
|
destContents := randomContents(64)
|
||||||
|
|
||||||
|
defer suite.StorageDriver.Delete(firstPart(sourcePath))
|
||||||
|
defer suite.StorageDriver.Delete(firstPart(destPath))
|
||||||
|
|
||||||
|
err := suite.StorageDriver.PutContent(sourcePath, sourceContents)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
err = suite.StorageDriver.PutContent(destPath, destContents)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
err = suite.StorageDriver.Move(sourcePath, destPath)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
received, err := suite.StorageDriver.GetContent(destPath)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
c.Assert(received, check.DeepEquals, sourceContents)
|
||||||
|
|
||||||
|
_, err = suite.StorageDriver.GetContent(sourcePath)
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMoveNonexistent checks that moving a nonexistent key fails and does not
|
||||||
|
// delete the data at the destination path.
|
||||||
func (suite *DriverSuite) TestMoveNonexistent(c *check.C) {
|
func (suite *DriverSuite) TestMoveNonexistent(c *check.C) {
|
||||||
|
contents := randomContents(32)
|
||||||
sourcePath := randomPath(32)
|
sourcePath := randomPath(32)
|
||||||
destPath := randomPath(32)
|
destPath := randomPath(32)
|
||||||
|
|
||||||
err := suite.StorageDriver.Move(sourcePath, destPath)
|
defer suite.StorageDriver.Delete(firstPart(destPath))
|
||||||
|
|
||||||
|
err := suite.StorageDriver.PutContent(destPath, contents)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
err = suite.StorageDriver.Move(sourcePath, destPath)
|
||||||
c.Assert(err, check.NotNil)
|
c.Assert(err, check.NotNil)
|
||||||
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
|
|
||||||
|
received, err := suite.StorageDriver.GetContent(destPath)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
c.Assert(received, check.DeepEquals, contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDelete checks that the delete operation removes data from the storage
|
// TestDelete checks that the delete operation removes data from the storage
|
||||||
|
@ -553,10 +598,15 @@ func (suite *DriverSuite) TestStatCall(c *check.C) {
|
||||||
fileName := randomFilename(32)
|
fileName := randomFilename(32)
|
||||||
filePath := path.Join(dirPath, fileName)
|
filePath := path.Join(dirPath, fileName)
|
||||||
|
|
||||||
defer suite.StorageDriver.Delete(dirPath)
|
defer suite.StorageDriver.Delete(firstPart(dirPath))
|
||||||
|
|
||||||
// Call on non-existent file/dir, check error.
|
// Call on non-existent file/dir, check error.
|
||||||
fi, err := suite.StorageDriver.Stat(filePath)
|
fi, err := suite.StorageDriver.Stat(dirPath)
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
|
c.Assert(fi, check.IsNil)
|
||||||
|
|
||||||
|
fi, err = suite.StorageDriver.Stat(filePath)
|
||||||
c.Assert(err, check.NotNil)
|
c.Assert(err, check.NotNil)
|
||||||
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
c.Assert(fi, check.IsNil)
|
c.Assert(fi, check.IsNil)
|
||||||
|
@ -601,9 +651,46 @@ func (suite *DriverSuite) TestStatCall(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestConcurrentStreamReads checks that multiple clients can safely read from
|
||||||
|
// the same file simultaneously with various offsets.
|
||||||
|
func (suite *DriverSuite) TestConcurrentStreamReads(c *check.C) {
|
||||||
|
var filesize int64 = 128 * 1024 * 1024
|
||||||
|
|
||||||
|
if testing.Short() {
|
||||||
|
filesize = 10 * 1024 * 1024
|
||||||
|
c.Log("Reducing file size to 10MB for short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := randomPath(32)
|
||||||
|
contents := randomContents(filesize)
|
||||||
|
|
||||||
|
defer suite.StorageDriver.Delete(firstPart(filename))
|
||||||
|
|
||||||
|
err := suite.StorageDriver.PutContent(filename, contents)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
readContents := func() {
|
||||||
|
defer wg.Done()
|
||||||
|
offset := rand.Int63n(int64(len(contents)))
|
||||||
|
reader, err := suite.StorageDriver.ReadStream(filename, offset)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
readContents, err := ioutil.ReadAll(reader)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
c.Assert(readContents, check.DeepEquals, contents[offset:])
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Add(10)
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
go readContents()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
// TestConcurrentFileStreams checks that multiple *os.File objects can be passed
|
// TestConcurrentFileStreams checks that multiple *os.File objects can be passed
|
||||||
// in to WriteStream concurrently without hanging.
|
// in to WriteStream concurrently without hanging.
|
||||||
// TODO(bbland): fix this test...
|
|
||||||
func (suite *DriverSuite) TestConcurrentFileStreams(c *check.C) {
|
func (suite *DriverSuite) TestConcurrentFileStreams(c *check.C) {
|
||||||
// if _, isIPC := suite.StorageDriver.(*ipc.StorageDriverClient); isIPC {
|
// if _, isIPC := suite.StorageDriver.(*ipc.StorageDriverClient); isIPC {
|
||||||
// c.Skip("Need to fix out-of-process concurrency")
|
// c.Skip("Need to fix out-of-process concurrency")
|
||||||
|
@ -632,8 +719,8 @@ func (suite *DriverSuite) testFileStreams(c *check.C, size int64) {
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
defer os.Remove(tf.Name())
|
defer os.Remove(tf.Name())
|
||||||
|
|
||||||
tfName := path.Base(tf.Name())
|
filename := randomPath(32)
|
||||||
defer suite.StorageDriver.Delete(tfName)
|
defer suite.StorageDriver.Delete(firstPart(filename))
|
||||||
|
|
||||||
contents := randomContents(size)
|
contents := randomContents(size)
|
||||||
|
|
||||||
|
@ -643,11 +730,11 @@ func (suite *DriverSuite) testFileStreams(c *check.C, size int64) {
|
||||||
tf.Sync()
|
tf.Sync()
|
||||||
tf.Seek(0, os.SEEK_SET)
|
tf.Seek(0, os.SEEK_SET)
|
||||||
|
|
||||||
nn, err := suite.StorageDriver.WriteStream(tfName, 0, tf)
|
nn, err := suite.StorageDriver.WriteStream(filename, 0, tf)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
c.Assert(nn, check.Equals, size)
|
c.Assert(nn, check.Equals, size)
|
||||||
|
|
||||||
reader, err := suite.StorageDriver.ReadStream(tfName, 0)
|
reader, err := suite.StorageDriver.ReadStream(filename, 0)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue