func (s *managedStorageSuite) TestPutPendingUpload(c *gc.C) {
	// Manually set up a scenario where there's a resource recorded
	// but the upload has not occurred.
	rc := blobstore.GetResourceCatalog(s.managedStorage)
	hash := "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"

	id, path, err := rc.Put(hash, 3)
	c.Assert(err, gc.IsNil)
	c.Assert(path, gc.Equals, "")
	managedResource := blobstore.ManagedResource{
		EnvUUID: "env",
		User:    "******",
		Path:    "environs/env/path/to/blob",
	}
	c.Assert(err, gc.IsNil)

	_, err = blobstore.PutManagedResource(s.managedStorage, managedResource, id)
	_, _, err = s.managedStorage.GetForEnvironment("env", "/path/to/blob")
	c.Assert(errors.Cause(err), gc.Equals, blobstore.ErrUploadPending)

	// Despite the upload being pending, a second concurrent upload will succeed.
	rdr := bytes.NewReader([]byte("abc"))
	err = s.managedStorage.PutForEnvironment("env", "/path/to/blob", rdr, 3)
	c.Assert(err, gc.IsNil)
	s.assertGet(c, "/path/to/blob", []byte("abc"))
}
func (s *managedStorageSuite) TestGetPendingUpload(c *gc.C) {
	// Manually set up a scenario where there's a resource recorded
	// but the upload has not occurred.
	rc := blobstore.GetResourceCatalog(s.managedStorage)
	id, _, err := rc.Put("foo", 100)
	c.Assert(err, gc.IsNil)
	managedResource := blobstore.ManagedResource{
		EnvUUID: "env",
		User:    "******",
		Path:    "environs/env/path/to/blob",
	}
	_, err = blobstore.PutManagedResource(s.managedStorage, managedResource, id)
	c.Assert(err, gc.IsNil)
	_, _, err = s.managedStorage.GetForEnvironment("env", "/path/to/blob")
	c.Assert(err, gc.Equals, blobstore.ErrUploadPending)
}
func (s *managedStorageSuite) TestPutRaceWhereCatalogEntryRemoved(c *gc.C) {
	blob := []byte("some resource")
	// Remove the resource catalog entry with the resourceId that we are about
	// to write to a managed resource entry.
	beforeFunc := []func(){
		nil, //  resourceCatalog Put()
		nil, //  managedResource Put()
		func() {
			// Shamelessly exploit our knowledge of how ids are made.
			sha384Hash := calculateCheckSum(c, 0, int64(len(blob)), blob)
			_, _, err := blobstore.GetResourceCatalog(s.managedStorage).Remove(sha384Hash)
			c.Assert(err, gc.IsNil)
		},
	}
	defer txntesting.SetBeforeHooks(c, s.txnRunner, beforeFunc...).Check()
	rdr := bytes.NewReader(blob)
	err := s.managedStorage.PutForEnvironment("env", "/path/to/blob", rdr, int64(len(blob)))
	c.Assert(err, gc.ErrorMatches, "unexpected deletion .*")
	s.assertResourceCatalogCount(c, 0)
}
func (s *managedStorageSuite) TestPutManagedResourceFail(c *gc.C) {
	var resourcePath string
	s.PatchValue(blobstore.PutResourceTxn, func(
		coll *mgo.Collection, managedResource blobstore.ManagedResource, resourceId string) (string, []txn.Op, error) {
		rc := blobstore.GetResourceCatalog(s.managedStorage)
		r, err := rc.Get(resourceId)
		c.Assert(err, gc.IsNil)
		resourcePath = r.Path
		return "", nil, errors.Errorf("some error")
	})
	// Attempt to put the data.
	blob := []byte("data")
	rdr := bytes.NewReader(blob)
	err := s.managedStorage.PutForEnvironment("env", "/some/path", rdr, int64(len(blob)))
	c.Assert(err, gc.ErrorMatches, "cannot update managed resource catalog: some error")

	// Now ensure there's no blob data left behind in storage, nor a resource catalog record.
	s.assertResourceCatalogCount(c, 0)
	_, err = s.resourceStorage.Get(resourcePath)
	c.Assert(err, gc.ErrorMatches, ".*not found")
}