[ARVADOS] updated: c15f086483884fb21d04ceac0ea8bd96308051bd

git at public.curoverse.com git at public.curoverse.com
Fri Aug 22 13:56:02 EDT 2014


Summary of changes:
 services/keepstore/keepstore_test.go   | 49 +++++++++++++++++++++++++++++++++-
 services/keepstore/volume.go           | 14 ++++++++++
 services/keepstore/volume_unix.go      | 13 ++++++++-
 services/keepstore/volume_unix_test.go | 35 ++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 2 deletions(-)

       via  c15f086483884fb21d04ceac0ea8bd96308051bd (commit)
      from  e386d20665a2bf9a59e314ad9efa5fddfffb8058 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit c15f086483884fb21d04ceac0ea8bd96308051bd
Author: Tim Pierce <twp at curoverse.com>
Date:   Fri Aug 22 13:52:33 2014 -0400

    3448: unit tests, bug fixes
    
    UnixVolume.Delete tests the return status of lockfile (oops, left out of
    previous commit)
    
    New unit/integration tests:
    
    * TestPutTouch (volume_unix_test.go): issues a volume.Put for a block
      that already exists, and confirms that the mtime of the existing block
      is updated.
    
    * TestPutBlockTouchFails (keepstore_test.go): issues PutBlock for a
      block that already exists but cannot be modified, confirms that the
      mtime on the old block is unchanged and that a new copy has been
      stored.
    
    Added a volume.Mtime() method to return the block mtime, to assist in
    testing.

diff --git a/services/keepstore/keepstore_test.go b/services/keepstore/keepstore_test.go
index d43a00e..2b7e411 100644
--- a/services/keepstore/keepstore_test.go
+++ b/services/keepstore/keepstore_test.go
@@ -217,7 +217,7 @@ func TestPutBlockCorrupt(t *testing.T) {
 	}
 }
 
-// PutBlockCollision
+// TestPutBlockCollision
 //     PutBlock returns a 400 Collision error when attempting to
 //     store a block that collides with another block on disk.
 //
@@ -245,6 +245,53 @@ func TestPutBlockCollision(t *testing.T) {
 	}
 }
 
+// TestPutBlockTouchFails
+//     When PutBlock is asked to PUT an existing block, but cannot
+//     modify the timestamp, it should write a second block.
+//
+func TestPutBlockTouchFails(t *testing.T) {
+	defer teardown()
+
+	// Prepare two test Keep volumes.
+	KeepVM = MakeTestVolumeManager(2)
+	defer func() { KeepVM.Quit() }()
+	vols := KeepVM.Volumes()
+
+	// Store a block and then make the underlying volume bad,
+	// so a subsequent attempt to update the file timestamp
+	// will fail.
+	vols[0].Put(TEST_HASH, BAD_BLOCK)
+	old_mtime, err := vols[0].Mtime(TEST_HASH)
+	if err != nil {
+		t.Fatalf("vols[0].Mtime(%s): %s\n", TEST_HASH, err)
+	}
+
+	// Mark the volume bad and call PutBlock.
+	vols[0].(*MockVolume).Bad = true
+	if err := PutBlock(TEST_BLOCK, TEST_HASH); err != nil {
+		t.Fatalf("PutBlock: %v", err)
+	}
+	vols[0].(*MockVolume).Bad = false
+
+	// Now the mtime on the block on vols[0] should be unchanged, and
+	// there should be a copy of the block on vols[1].
+	new_mtime, err := vols[0].Mtime(TEST_HASH)
+	if err != nil {
+		t.Fatalf("vols[0].Mtime(%s): %s\n", TEST_HASH, err)
+	}
+	if !new_mtime.Equal(old_mtime) {
+		t.Errorf("bad block mtimes do not match:\nold_mtime = %v\nnew_mtime = %v\n",
+			old_mtime, new_mtime)
+	}
+	result, err := vols[1].Get(TEST_HASH)
+	if err != nil {
+		t.Fatalf("vols[1]: %v", err)
+	}
+	if bytes.Compare(result, TEST_BLOCK) != 0 {
+		t.Errorf("new block does not match test block\nnew block = %v\n", result)
+	}
+}
+
 // ========================================
 // FindKeepVolumes tests.
 // ========================================
diff --git a/services/keepstore/volume.go b/services/keepstore/volume.go
index 0406c3d..6fb1a1e 100644
--- a/services/keepstore/volume.go
+++ b/services/keepstore/volume.go
@@ -16,6 +16,7 @@ type Volume interface {
 	Get(loc string) ([]byte, error)
 	Put(loc string, block []byte) error
 	Touch(loc string) error
+	Mtime(loc string) (time.Time, error)
 	Index(prefix string) string
 	Delete(loc string) error
 	Status() *VolumeStatus
@@ -66,6 +67,19 @@ func (v *MockVolume) Touch(loc string) error {
 	return nil
 }
 
+func (v *MockVolume) Mtime(loc string) (time.Time, error) {
+	var mtime time.Time
+	var err error
+	if v.Bad {
+		err = errors.New("Bad volume")
+	} else if t, ok := v.Timestamps[loc]; ok {
+		mtime = t
+	} else {
+		err = os.ErrNotExist
+	}
+	return mtime, err
+}
+
 func (v *MockVolume) Index(prefix string) string {
 	var result string
 	for loc, block := range v.Store {
diff --git a/services/keepstore/volume_unix.go b/services/keepstore/volume_unix.go
index f439978..75a7522 100644
--- a/services/keepstore/volume_unix.go
+++ b/services/keepstore/volume_unix.go
@@ -112,6 +112,15 @@ func (v *UnixVolume) Touch(loc string) error {
 	return syscall.Utime(p, &utime)
 }
 
+func (v *UnixVolume) Mtime(loc string) (time.Time, error) {
+	p := v.blockPath(loc)
+	if fi, err := os.Stat(p); err != nil {
+		return time.Time{}, err
+	} else {
+		return fi.ModTime(), nil
+	}
+}
+
 // Read retrieves a block identified by the locator string "loc", and
 // returns its contents as a byte slice.
 //
@@ -250,7 +259,9 @@ func (v *UnixVolume) Delete(loc string) error {
 	if err != nil {
 		return err
 	}
-	lockfile(f)
+	if e := lockfile(f); e != nil {
+		return e
+	}
 	defer unlockfile(f)
 
 	// If the block has been PUT more recently than -permission_ttl,
diff --git a/services/keepstore/volume_unix_test.go b/services/keepstore/volume_unix_test.go
index 278e656..7a1c06c 100644
--- a/services/keepstore/volume_unix_test.go
+++ b/services/keepstore/volume_unix_test.go
@@ -100,6 +100,41 @@ func TestPutBadVolume(t *testing.T) {
 	}
 }
 
+// TestPutTouch
+//     Test that when applying PUT to a block that already exists,
+//     the block's modification time is updated.
+func TestPutTouch(t *testing.T) {
+	v := TempUnixVolume(t, false)
+	defer _teardown(v)
+
+	if err := v.Put(TEST_HASH, TEST_BLOCK); err != nil {
+		t.Error(err)
+	}
+	old_mtime, err := v.Mtime(TEST_HASH)
+	if err != nil {
+		t.Error(err)
+	}
+	if old_mtime.IsZero() {
+		t.Errorf("v.Mtime(%s) returned a zero mtime\n", TEST_HASH)
+	}
+	// Sleep for 1s, then put the block again.  The volume
+	// should report a more recent mtime.
+	// TODO(twp): this would be better handled with a mock Time object.
+	time.Sleep(time.Second)
+	if err := v.Put(TEST_HASH, TEST_BLOCK); err != nil {
+		t.Error(err)
+	}
+	new_mtime, err := v.Mtime(TEST_HASH)
+	if err != nil {
+		t.Error(err)
+	}
+
+	if !new_mtime.After(old_mtime) {
+		t.Errorf("v.Put did not update the block mtime:\nold_mtime = %v\nnew_mtime = %v\n",
+			old_mtime, new_mtime)
+	}
+}
+
 // Serialization tests: launch a bunch of concurrent
 //
 // TODO(twp): show that the underlying Read/Write operations executed

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list