Ejemplo n.º 1
0
func (t *ConnTest) BucketsAreSegregatedByName() {
	const objName = "baz"
	var contents []byte
	var err error

	b0, err := t.conn.OpenBucket(t.ctx, "foo")
	AssertEq(nil, err)

	b1, err := t.conn.OpenBucket(t.ctx, "bar")
	AssertEq(nil, err)

	// Add an object with the same name but different contents to each of two
	// buckets.
	_, err = gcsutil.CreateObject(t.ctx, b0, objName, []byte("taco"))
	AssertEq(nil, err)

	_, err = gcsutil.CreateObject(t.ctx, b1, objName, []byte("burrito"))
	AssertEq(nil, err)

	// Each should have stored it independently.
	contents, err = gcsutil.ReadObject(t.ctx, b0, objName)
	AssertEq(nil, err)
	ExpectEq("taco", string(contents))

	contents, err = gcsutil.ReadObject(t.ctx, b1, objName)
	AssertEq(nil, err)
	ExpectEq("burrito", string(contents))
}
Ejemplo n.º 2
0
func (t *IntegrationTest) BackingObjectHasBeenOverwritten_BeforeReading() {
	// Create an object, then create the mutable object wrapper around it.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Overwrite the GCS object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, "foo", "burrito")
	AssertEq(nil, err)

	// Sync doesn't need to do anything.
	rl, newObj, err := t.sync(o)

	AssertEq(nil, err)
	ExpectEq(nil, rl)
	ExpectEq(nil, newObj)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mc.ReadAt(t.ctx, []byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mc.Truncate(t.ctx, 10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mc.WriteAt(t.ctx, []byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}
Ejemplo n.º 3
0
func (t *DirTest) CloneToChildFile_DestinationExists() {
	const srcName = "blah/baz"
	dstName := path.Join(dirInodeName, "qux")

	var o *gcs.Object
	var err error

	// Create the source.
	src, err := gcsutil.CreateObject(t.ctx, t.bucket, srcName, []byte("taco"))
	AssertEq(nil, err)

	// And a destination object that will be overwritten.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, dstName, []byte(""))
	AssertEq(nil, err)

	// Call the inode.
	o, err = t.in.CloneToChildFile(t.ctx, path.Base(dstName), src)
	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dstName, o.Name)
	ExpectFalse(inode.IsSymlink(o))
	ExpectEq(len("taco"), o.Size)

	// Check resulting contents.
	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, dstName)
	AssertEq(nil, err)
	ExpectEq("taco", string(contents))
}
Ejemplo n.º 4
0
func (t *DirTest) LookUpChild_ImplicitDirOnly_Enabled() {
	const name = "qux"
	objName := path.Join(dirInodeName, name) + "/"

	var err error

	// Enable implicit dirs.
	t.resetInode(true)

	// Create an object that implicitly defines the directory.
	otherObjName := path.Join(objName, "asdf")
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, otherObjName, []byte(""))
	AssertEq(nil, err)

	// Looking up the name should work.
	result, err := t.in.LookUpChild(t.ctx, name)

	AssertEq(nil, err)
	ExpectEq(nil, result.Object)

	ExpectEq(objName, result.FullName)
	ExpectTrue(result.ImplicitDir)

	// A conflict marker should not work.
	result, err = t.in.LookUpChild(t.ctx, name+inode.ConflictingFileNameSuffix)
	AssertEq(nil, err)
	ExpectFalse(result.Exists())
}
Ejemplo n.º 5
0
func (t *DirTest) LookUpChild_DirOnly() {
	const name = "qux"
	objName := path.Join(dirInodeName, name) + "/"

	var o *gcs.Object
	var err error

	// Create a backing object.
	createObj, err := gcsutil.CreateObject(t.ctx, t.bucket, objName, []byte(""))
	AssertEq(nil, err)

	// Look up with the proper name.
	result, err := t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(objName, result.FullName)
	ExpectEq(objName, o.Name)
	ExpectEq(createObj.Generation, o.Generation)
	ExpectEq(createObj.Size, o.Size)

	// A conflict marker name shouldn't work.
	result, err = t.in.LookUpChild(t.ctx, name+inode.ConflictingFileNameSuffix)
	AssertEq(nil, err)
	ExpectFalse(result.Exists())
}
Ejemplo n.º 6
0
func (t *PrefixBucketTest) DeleteObject() {
	var err error
	suffix := "taco"
	name := t.prefix + suffix
	contents := "foobar"

	// Create an object through the back door.
	_, err = gcsutil.CreateObject(t.ctx, t.wrapped, name, []byte(contents))
	AssertEq(nil, err)

	// Delete it.
	err = t.bucket.DeleteObject(
		t.ctx,
		&gcs.DeleteObjectRequest{
			Name: suffix,
		})

	AssertEq(nil, err)

	// It should be gone.
	_, err = t.wrapped.StatObject(
		t.ctx,
		&gcs.StatObjectRequest{
			Name: name,
		})

	ExpectThat(err, HasSameTypeAs(&gcs.NotFoundError{}))
}
Ejemplo n.º 7
0
func (t *FileTest) SetMtime_SourceObjectGenerationChanged() {
	var err error

	// Clobber the backing object.
	newObj, err := gcsutil.CreateObject(
		t.ctx,
		t.bucket,
		t.in.Name(),
		[]byte("burrito"))

	AssertEq(nil, err)

	// Set mtime.
	mtime := time.Now().UTC().Add(123 * time.Second)
	err = t.in.SetMtime(t.ctx, mtime)
	AssertEq(nil, err)

	// The object in the bucket should not have been changed.
	statReq := &gcs.StatObjectRequest{Name: t.in.Name()}
	o, err := t.bucket.StatObject(t.ctx, statReq)

	AssertEq(nil, err)
	ExpectEq(newObj.Generation, o.Generation)
	ExpectEq(0, len(o.Metadata))
}
Ejemplo n.º 8
0
func (t *IntegrationTest) WithinLeaserLimit() {
	AssertLt(len("taco"), fileLeaserLimitBytes)

	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Extend to be up against the leaser limit, then write out to GCS, which
	// should downgrade to a read lease.
	err = t.mc.Truncate(t.ctx, fileLeaserLimitBytes)
	AssertEq(nil, err)

	rl, _, err := t.sync(o)
	AssertEq(nil, err)

	// The backing object should be present and contain the correct contents.
	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, o.Name)
	AssertEq(nil, err)
	ExpectEq(fileLeaserLimitBytes, len(contents))

	// Delete the backing object.
	err = t.bucket.DeleteObject(t.ctx, &gcs.DeleteObjectRequest{Name: o.Name})
	AssertEq(nil, err)

	// We should still be able to read the contents, because the read lease
	// should still be valid.
	buf := make([]byte, 4)
	n, err := rl.ReadAt(buf, 0)

	AssertEq(nil, err)
	ExpectEq("taco", string(buf[0:n]))
}
Ejemplo n.º 9
0
func (t *IntegrationTest) TruncateThenSync() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Truncate.
	err = t.mc.Truncate(t.ctx, 2)
	AssertEq(nil, err)

	// Sync should save out the new generation.
	rl, newObj, err := t.sync(o)
	AssertEq(nil, err)

	ExpectNe(o.Generation, newObj.Generation)
	ExpectEq(t.objectGeneration("foo"), newObj.Generation)

	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, "foo")
	AssertEq(nil, err)
	ExpectEq("ta", string(contents))

	// Read via the lease.
	_, err = rl.Seek(0, 0)
	AssertEq(nil, err)

	contents, err = ioutil.ReadAll(rl)
	AssertEq(nil, err)
	ExpectEq("ta", string(contents))
}
Ejemplo n.º 10
0
func (t *PrefixBucketTest) CopyObject() {
	var err error
	suffix := "taco"
	name := t.prefix + suffix
	contents := "foobar"

	// Create an object through the back door.
	_, err = gcsutil.CreateObject(t.ctx, t.wrapped, name, []byte(contents))
	AssertEq(nil, err)

	// Copy it to a new name.
	newSuffix := "burrito"
	o, err := t.bucket.CopyObject(
		t.ctx,
		&gcs.CopyObjectRequest{
			SrcName: suffix,
			DstName: newSuffix,
		})

	AssertEq(nil, err)
	ExpectEq(newSuffix, o.Name)

	// Read it through the back door.
	actual, err := gcsutil.ReadObject(t.ctx, t.wrapped, t.prefix+newSuffix)
	AssertEq(nil, err)
	ExpectEq(contents, string(actual))
}
Ejemplo n.º 11
0
func (t *IntegrationTest) LargerThanLeaserLimit() {
	AssertLt(len("taco"), fileLeaserLimitBytes)

	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Extend to be past the leaser limit, then write out to GCS, which should
	// downgrade to a read lease.
	err = t.mc.Truncate(t.ctx, fileLeaserLimitBytes+1)
	AssertEq(nil, err)

	rl, _, err := t.sync(o)
	AssertEq(nil, err)

	// The backing object should be present and contain the correct contents.
	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, o.Name)
	AssertEq(nil, err)
	ExpectEq(fileLeaserLimitBytes+1, len(contents))

	// Delete the backing object.
	err = t.bucket.DeleteObject(t.ctx, &gcs.DeleteObjectRequest{Name: o.Name})
	AssertEq(nil, err)

	// The contents should be lost, because the leaser should have revoked the
	// read lease.
	_, err = rl.ReadAt(make([]byte, len(contents)), 0)
	ExpectThat(err, Error(HasSubstr("revoked")))
}
Ejemplo n.º 12
0
func (t *IntegrationTest) UpdateUpdatesCache() {
	const name = "taco"
	var err error

	// Create an object through the back door.
	_, err = gcsutil.CreateObject(t.ctx, t.wrapped, name, []byte{})
	AssertEq(nil, err)

	// Update it, putting the new version in cache.
	updateReq := &gcs.UpdateObjectRequest{
		Name: name,
	}

	_, err = t.bucket.UpdateObject(t.ctx, updateReq)
	AssertEq(nil, err)

	// Delete the object through the back door.
	err = t.wrapped.DeleteObject(t.ctx, &gcs.DeleteObjectRequest{Name: name})
	AssertEq(nil, err)

	// StatObject should still see it.
	o, err := t.stat(name)
	AssertEq(nil, err)
	ExpectNe(nil, o)
}
Ejemplo n.º 13
0
func (t *IntegrationTest) BackingObjectHasBeenDeleted_BeforeReading() {
	// Create an object to obtain a record, then delete it.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	err = t.bucket.DeleteObject(t.ctx, &gcs.DeleteObjectRequest{Name: o.Name})
	AssertEq(nil, err)

	// Create a mutable object around it.
	t.create(o)

	// Sync doesn't need to do anything.
	rl, newObj, err := t.sync(o)

	AssertEq(nil, err)
	ExpectEq(nil, rl)
	ExpectEq(nil, newObj)

	// Anything that needs to fault in the contents should fail.
	_, err = t.mc.ReadAt(t.ctx, []byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))

	err = t.mc.Truncate(t.ctx, 10)
	ExpectThat(err, Error(HasSubstr("not found")))

	_, err = t.mc.WriteAt(t.ctx, []byte{}, 0)
	ExpectThat(err, Error(HasSubstr("not found")))
}
Ejemplo n.º 14
0
func (t *IntegrationTest) TruncateThenSync() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", []byte("taco"))
	AssertEq(nil, err)

	t.create(o)

	// Truncate.
	t.clock.AdvanceTime(time.Second)
	truncateTime := t.clock.Now()
	err = t.tf.Truncate(2)
	t.clock.AdvanceTime(time.Second)

	AssertEq(nil, err)

	// Sync should save out the new generation.
	newObj, err := t.sync(o)
	AssertEq(nil, err)

	ExpectNe(o.Generation, newObj.Generation)
	ExpectEq(t.objectGeneration("foo"), newObj.Generation)
	ExpectEq(
		truncateTime.UTC().Format(time.RFC3339Nano),
		newObj.Metadata["gcsfuse_mtime"])

	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, "foo")
	AssertEq(nil, err)
	ExpectEq("ta", string(contents))
}
Ejemplo n.º 15
0
func (t *IntegrationTest) UpdateInvalidatesNegativeCache() {
	const name = "taco"
	var err error

	// Stat an unknown object, getting it into the negative cache.
	_, err = t.stat(name)
	AssertThat(err, HasSameTypeAs(&gcs.NotFoundError{}))

	// Create the object through the back door.
	_, err = gcsutil.CreateObject(t.ctx, t.wrapped, name, []byte{})
	AssertEq(nil, err)

	// Update the object.
	updateReq := &gcs.UpdateObjectRequest{
		Name: name,
	}

	_, err = t.bucket.UpdateObject(t.ctx, updateReq)
	AssertEq(nil, err)

	// Now StatObject should see it.
	o, err := t.stat(name)
	AssertEq(nil, err)
	ExpectNe(nil, o)
}
Ejemplo n.º 16
0
func (t *FileTest) Sync_Clobbered() {
	var err error

	// Truncate downward.
	err = t.in.Truncate(t.ctx, 2)
	AssertEq(nil, err)

	// Clobber the backing object.
	newObj, err := gcsutil.CreateObject(
		t.ctx,
		t.bucket,
		t.in.Name(),
		[]byte("burrito"))

	AssertEq(nil, err)

	// Sync. The call should succeed, but nothing should change.
	err = t.in.Sync(t.ctx)

	AssertEq(nil, err)
	ExpectEq(t.backingObj.Generation, t.in.SourceGeneration().Object)
	ExpectEq(t.backingObj.MetaGeneration, t.in.SourceGeneration().Metadata)

	// The object in the bucket should not have been changed.
	statReq := &gcs.StatObjectRequest{Name: t.in.Name()}
	o, err := t.bucket.StatObject(t.ctx, statReq)

	AssertEq(nil, err)
	ExpectEq(newObj.Generation, o.Generation)
	ExpectEq(newObj.Size, o.Size)
}
Ejemplo n.º 17
0
func (t *ConnTest) BucketContentsAreStable() {
	const bucketName = "foo"
	const objName = "bar"

	var err error

	// Open the bucket.
	bucket, err := t.conn.OpenBucket(t.ctx, bucketName)
	AssertEq(nil, err)

	// Add an object to a bucket.
	_, err = gcsutil.CreateObject(
		t.ctx,
		bucket,
		objName,
		[]byte("taco"))

	AssertEq(nil, err)

	// Grab the bucket again. It should still be there.
	contents, err := gcsutil.ReadObject(
		t.ctx,
		bucket,
		objName)

	AssertEq(nil, err)
	ExpectEq("taco", string(contents))
}
Ejemplo n.º 18
0
func (t *DirTest) LookUpChild_FileAndDirAndImplicitDir_Enabled() {
	const name = "qux"
	fileObjName := path.Join(dirInodeName, name)
	dirObjName := path.Join(dirInodeName, name) + "/"

	var o *gcs.Object
	var err error

	// Enable implicit dirs.
	t.resetInode(true)

	// Create backing objects.
	fileObj, err := gcsutil.CreateObject(t.ctx, t.bucket, fileObjName, []byte("taco"))
	AssertEq(nil, err)

	dirObj, err := gcsutil.CreateObject(t.ctx, t.bucket, dirObjName, []byte(""))
	AssertEq(nil, err)

	// Create an object that implicitly defines the directory.
	otherObjName := path.Join(dirInodeName, name) + "/asdf"
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, otherObjName, []byte(""))
	AssertEq(nil, err)

	// Look up with the proper name.
	result, err := t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dirObjName, result.FullName)
	ExpectEq(dirObjName, o.Name)
	ExpectEq(dirObj.Generation, o.Generation)
	ExpectEq(dirObj.Size, o.Size)

	// Look up with the conflict marker name.
	result, err = t.in.LookUpChild(t.ctx, name+inode.ConflictingFileNameSuffix)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(fileObjName, result.FullName)
	ExpectEq(fileObjName, o.Name)
	ExpectEq(fileObj.Generation, o.Generation)
	ExpectEq(fileObj.Size, o.Size)
}
Ejemplo n.º 19
0
func (t *DirTest) LookUpChild_TypeCaching() {
	const name = "qux"
	fileObjName := path.Join(dirInodeName, name)
	dirObjName := path.Join(dirInodeName, name) + "/"

	var o *gcs.Object
	var err error

	// Create a backing object for a file.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, fileObjName, []byte("taco"))
	AssertEq(nil, err)

	// Look up; we should get the file.
	result, err := t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(fileObjName, o.Name)

	// Create a backing object for a directory.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, dirObjName, []byte("taco"))
	AssertEq(nil, err)

	// Look up again. Even though the directory should shadow the file, because
	// we've cached only seeing the file that's what we should get back.
	result, err = t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(fileObjName, o.Name)

	// But after the TTL expires, the behavior should flip.
	t.clock.AdvanceTime(typeCacheTTL + time.Millisecond)

	result, err = t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dirObjName, o.Name)
}
Ejemplo n.º 20
0
func (t *IntegrationTest) BackingObjectHasBeenOverwritten_AfterReading() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Fault in the contents.
	_, err = t.mc.ReadAt(t.ctx, []byte{}, 0)
	AssertEq(nil, err)

	// Overwrite the backing object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, "foo", "burrito")
	AssertEq(nil, err)

	// Reading and modications should still work.
	_, err = t.mc.ReadAt(t.ctx, []byte{}, 0)
	AssertEq(nil, err)

	_, err = t.mc.WriteAt(t.ctx, []byte("a"), 0)
	AssertEq(nil, err)

	truncateTime := t.clock.Now()
	err = t.mc.Truncate(t.ctx, 3)
	AssertEq(nil, err)
	t.clock.AdvanceTime(time.Second)

	// Stat should see the current state.
	sr, err := t.mc.Stat(t.ctx)
	AssertEq(nil, err)

	ExpectEq(3, sr.Size)
	ExpectEq(0, sr.DirtyThreshold)
	ExpectThat(sr.Mtime, Pointee(timeutil.TimeEq(truncateTime)))

	// Sync should fail with a precondition error.
	_, _, err = t.sync(o)
	ExpectThat(err, HasSameTypeAs(&gcs.PreconditionError{}))

	// The newer version should still be present.
	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, o.Name)
	AssertEq(nil, err)
	ExpectEq("burrito", string(contents))
}
Ejemplo n.º 21
0
func (t *ForeignModsTest) ReadFromFile_Large() {
	randSrc := rand.New(rand.NewSource(0xdeadbeef))

	// Create some random contents.
	const contentLen = 1 << 22
	contents := randBytes(contentLen)

	// Repeatedly:
	//
	//  *  Create an object with the random contents.
	//  *  Read a random range of it.
	//  *  Verify the result.
	//
	var buf [contentLen]byte
	runOnce := func() {
		// Create an object.
		_, err := gcsutil.CreateObject(
			t.ctx,
			t.bucket,
			"foo",
			contents)

		AssertEq(nil, err)

		// Attempt to open it.
		f, err := os.Open(path.Join(t.mfs.Dir(), "foo"))
		AssertEq(nil, err)
		defer func() { AssertEq(nil, f.Close()) }()

		// Read part of it.
		offset := randSrc.Int63n(contentLen + 1)
		size := randSrc.Intn(int(contentLen - offset))

		n, err := f.ReadAt(buf[:size], offset)
		if offset+int64(size) == contentLen && err == io.EOF {
			err = nil
		}

		AssertEq(nil, err)
		AssertEq(size, n)
		AssertTrue(
			bytes.Equal(contents[offset:offset+int64(size)], buf[:n]),
			"offset: %d\n"+
				"size:   %d\n"+
				"n:      %d",
			offset,
			size,
			n)
	}

	start := time.Now()
	for time.Since(start) < 2*time.Second {
		runOnce()
	}
}
Ejemplo n.º 22
0
func (t *DirTest) LookUpChild_SymlinkAndDir() {
	const name = "qux"
	linkObjName := path.Join(dirInodeName, name)
	dirObjName := path.Join(dirInodeName, name) + "/"

	var o *gcs.Object
	var err error

	// Create backing objects.
	linkObj, err := gcsutil.CreateObject(t.ctx, t.bucket, linkObjName, []byte("taco"))
	AssertEq(nil, err)

	err = t.setSymlinkTarget(linkObjName, "blah")
	AssertEq(nil, err)

	dirObj, err := gcsutil.CreateObject(t.ctx, t.bucket, dirObjName, []byte(""))
	AssertEq(nil, err)

	// Look up with the proper name.
	result, err := t.in.LookUpChild(t.ctx, name)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dirObjName, result.FullName)
	ExpectEq(dirObjName, o.Name)
	ExpectEq(dirObj.Generation, o.Generation)
	ExpectEq(dirObj.Size, o.Size)

	// Look up with the conflict marker name.
	result, err = t.in.LookUpChild(t.ctx, name+inode.ConflictingFileNameSuffix)
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(linkObjName, result.FullName)
	ExpectEq(linkObjName, o.Name)
	ExpectEq(linkObj.Generation, o.Generation)
	ExpectEq(linkObj.Size, o.Size)
}
Ejemplo n.º 23
0
func (t *ReadOnlyTest) ModifyFile() {
	// Create an object in the bucket.
	_, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	// Opening it for writing should fail.
	f, err := os.OpenFile(path.Join(t.Dir, "foo"), os.O_RDWR, 0)
	f.Close()

	ExpectThat(err, Error(HasSubstr("read-only")))
}
Ejemplo n.º 24
0
func (t *DirTest) CloneToChildFile_TypeCaching() {
	const srcName = "blah/baz"
	dstName := path.Join(dirInodeName, "qux")

	var o *gcs.Object
	var err error

	// Create the source.
	src, err := gcsutil.CreateObject(t.ctx, t.bucket, srcName, []byte(""))
	AssertEq(nil, err)

	// Clone to the destination.
	_, err = t.in.CloneToChildFile(t.ctx, path.Base(dstName), src)
	AssertEq(nil, err)

	// Create a backing object for a directory.
	dirObjName := dstName + "/"
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, dirObjName, []byte(""))
	AssertEq(nil, err)

	// Look up the name. Even though the directory should shadow the file,
	// because we've cached only seeing the file that's what we should get back.
	result, err := t.in.LookUpChild(t.ctx, path.Base(dstName))
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dstName, o.Name)

	// But after the TTL expires, the behavior should flip.
	t.clock.AdvanceTime(typeCacheTTL + time.Millisecond)

	result, err = t.in.LookUpChild(t.ctx, path.Base(dstName))
	o = result.Object

	AssertEq(nil, err)
	AssertNe(nil, o)

	ExpectEq(dirObjName, o.Name)
}
Ejemplo n.º 25
0
func (t *IntegrationTest) Stat_InitialState() {
	// Create.
	o, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	t.create(o)

	// Stat.
	sr, err := t.mc.Stat(t.ctx)
	AssertEq(nil, err)

	ExpectEq(o.Size, sr.Size)
	ExpectEq(o.Size, sr.DirtyThreshold)
	ExpectEq(nil, sr.Mtime)
}
Ejemplo n.º 26
0
func (t *DirTest) CreateChildDir_Exists() {
	const name = "qux"
	objName := path.Join(dirInodeName, name) + "/"

	var err error

	// Create an existing backing object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, objName, []byte("taco"))
	AssertEq(nil, err)

	// Call the inode.
	_, err = t.in.CreateChildDir(t.ctx, name)
	ExpectThat(err, Error(HasSubstr("Precondition")))
	ExpectThat(err, Error(HasSubstr("exists")))
}
Ejemplo n.º 27
0
func (t *ReadOnlyTest) DeleteFile() {
	// Create an object in the bucket.
	_, err := gcsutil.CreateObject(t.ctx, t.bucket, "foo", "taco")
	AssertEq(nil, err)

	// Attempt to delete it via the file system.
	err = os.Remove(path.Join(t.Dir, "foo"))
	ExpectThat(err, Error(HasSubstr("read-only")))

	// the bucket should not have been modified.
	contents, err := gcsutil.ReadObject(t.ctx, t.bucket, "foo")

	AssertEq(nil, err)
	ExpectEq("taco", string(contents))
}
Ejemplo n.º 28
0
func (t *IntegrationTest) StatAddsToNegativeCache() {
	const name = "taco"
	var err error

	// Stat an unknown object, getting it into the negative cache.
	_, err = t.stat(name)
	AssertThat(err, HasSameTypeAs(&gcs.NotFoundError{}))

	// Create the object through the back door.
	_, err = gcsutil.CreateObject(t.ctx, t.wrapped, name, []byte{})
	AssertEq(nil, err)

	// StatObject should still not see it yet.
	_, err = t.stat(name)
	ExpectThat(err, HasSameTypeAs(&gcs.NotFoundError{}))
}
Ejemplo n.º 29
0
func (t *DirTest) CreateChildSymlink_Exists() {
	const name = "qux"
	const target = "taco"
	objName := path.Join(dirInodeName, name)

	var err error

	// Create an existing backing object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, objName, "")
	AssertEq(nil, err)

	// Call the inode.
	_, err = t.in.CreateChildSymlink(t.ctx, name, target)
	ExpectThat(err, Error(HasSubstr("Precondition")))
	ExpectThat(err, Error(HasSubstr("exists")))
}
Ejemplo n.º 30
0
func (t *IntegrationTest) CreateInsertsIntoCache() {
	const name = "taco"
	var err error

	// Create an object.
	_, err = gcsutil.CreateObject(t.ctx, t.bucket, name, []byte{})
	AssertEq(nil, err)

	// Delete it through the back door.
	err = t.wrapped.DeleteObject(t.ctx, &gcs.DeleteObjectRequest{Name: name})
	AssertEq(nil, err)

	// StatObject should still see it.
	o, err := t.stat(name)
	AssertEq(nil, err)
	ExpectNe(nil, o)
}