Merge pull request #837 from BrianBland/ng-storagedriver-tests
Various storagedriver test additions/improvementsmaster
						commit
						0317f17c41
					
				|  | @ -90,18 +90,16 @@ 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, | 			Body:   manifestBytes, | ||||||
| 				Body:   manifestBytes, |  | ||||||
| 			}, |  | ||||||
| 			Response: testutil.Response{ |  | ||||||
| 				StatusCode: http.StatusOK, |  | ||||||
| 			}, |  | ||||||
| 		}, | 		}, | ||||||
| 	}...)) | 		Response: testutil.Response{ | ||||||
|  | 			StatusCode: http.StatusOK, | ||||||
|  | 		}, | ||||||
|  | 	})) | ||||||
| 	server := httptest.NewServer(handler) | 	server := httptest.NewServer(handler) | ||||||
| 	client := New(server.URL) | 	client := New(server.URL) | ||||||
| 	objectStore := &memoryObjectStore{ | 	objectStore := &memoryObjectStore{ | ||||||
|  | @ -183,18 +181,16 @@ 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, |  | ||||||
| 			}, |  | ||||||
| 			Response: testutil.Response{ |  | ||||||
| 				StatusCode: http.StatusOK, |  | ||||||
| 				Body:       manifestBytes, |  | ||||||
| 			}, |  | ||||||
| 		}, | 		}, | ||||||
| 	}...)) | 		Response: testutil.Response{ | ||||||
|  | 			StatusCode: http.StatusOK, | ||||||
|  | 			Body:       manifestBytes, | ||||||
|  | 		}, | ||||||
|  | 	})) | ||||||
| 	server := httptest.NewServer(handler) | 	server := httptest.NewServer(handler) | ||||||
| 	client := New(server.URL) | 	client := New(server.URL) | ||||||
| 	objectStore := &memoryObjectStore{ | 	objectStore := &memoryObjectStore{ | ||||||
|  | @ -306,18 +302,16 @@ 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, |  | ||||||
| 				}, |  | ||||||
| 				Response: testutil.Response{ |  | ||||||
| 					StatusCode: http.StatusOK, |  | ||||||
| 					Body:       manifestBytes, |  | ||||||
| 				}, |  | ||||||
| 			}, | 			}, | ||||||
| 		}...) | 			Response: testutil.Response{ | ||||||
|  | 				StatusCode: http.StatusOK, | ||||||
|  | 				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 New Issue