From f5f007e1839badf162decc04314789d74e2cfe49 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Sun, 9 Oct 2016 05:38:17 +0530 Subject: [PATCH] Test: Add test case for xl.HealObject() (#2884) fixes #2842 --- cmd/xl-v1-healing.go | 6 +-- cmd/xl-v1-object_test.go | 87 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/cmd/xl-v1-healing.go b/cmd/xl-v1-healing.go index 5fc320652..70ffe3bd3 100644 --- a/cmd/xl-v1-healing.go +++ b/cmd/xl-v1-healing.go @@ -16,9 +16,7 @@ package cmd -import ( - "time" -) +import "time" // commonTime returns a maximally occurring time from a list of time. func commonTime(modTimes []time.Time) (modTime time.Time) { @@ -105,7 +103,7 @@ func outDatedDisks(disks []StorageAPI, partsMetadata []xlMetaV1, errs []error) ( outDatedDisks = make([]StorageAPI, len(disks)) latestDisks, _ := listOnlineDisks(disks, partsMetadata, errs) for index, disk := range latestDisks { - if errs[index] == errFileNotFound { + if errorCause(errs[index]) == errFileNotFound { outDatedDisks[index] = disks[index] continue } diff --git a/cmd/xl-v1-object_test.go b/cmd/xl-v1-object_test.go index 6c8957740..d6df35c82 100644 --- a/cmd/xl-v1-object_test.go +++ b/cmd/xl-v1-object_test.go @@ -21,7 +21,12 @@ import ( "crypto/md5" "encoding/hex" "io/ioutil" + "math/rand" + "os" + "path" + "reflect" "testing" + "time" ) func TestRepeatPutObjectPart(t *testing.T) { @@ -259,3 +264,85 @@ func TestPutObjectNoQuorum(t *testing.T) { // Cleanup backend directories. removeRoots(fsDirs) } + +func TestHealObject(t *testing.T) { + obj, fsDirs, err := prepareXL() + if err != nil { + t.Fatal(err) + } + defer removeRoots(fsDirs) + xl := obj.(xlObjects) + + // Create "bucket" + err = obj.MakeBucket("bucket") + if err != nil { + t.Fatal(err) + } + + bucket := "bucket" + object := "object" + + data := make([]byte, 1*1024*1024) + length := int64(len(data)) + _, err = rand.Read(data) + if err != nil { + t.Fatal(err) + } + + _, err = obj.PutObject(bucket, object, length, bytes.NewReader(data), nil, "") + if err != nil { + t.Fatal(err) + } + + disk := xl.storageDisks[0] + xlMetaPreHeal, err := readXLMeta(disk, bucket, object) + if err != nil { + t.Fatal(err) + } + + // Remove the object - to simulate the case where the disk was down when the object + // was created. + err = os.RemoveAll(path.Join(fsDirs[0], bucket, object)) + if err != nil { + t.Fatal(err) + } + + err = xl.HealObject(bucket, object) + if err != nil { + t.Fatal(err) + } + + xlMetaPostHeal, err := readXLMeta(disk, bucket, object) + if err != nil { + t.Fatal(err) + } + + // After heal the meta file should be as expected. + if !reflect.DeepEqual(xlMetaPreHeal, xlMetaPostHeal) { + t.Fatal("HealObject failed") + } + + // Write xl.json with different modtime to simulate the case where a disk had + // gone down when an object was replaced by a new object. + xlMetaOutDated := xlMetaPreHeal + xlMetaOutDated.Stat.ModTime = time.Now() + err = writeXLMetadata(disk, bucket, object, xlMetaOutDated) + if err != nil { + t.Fatal(err) + } + + err = xl.HealObject(bucket, object) + if err != nil { + t.Fatal(err) + } + + xlMetaPostHeal, err = readXLMeta(disk, bucket, object) + if err != nil { + t.Fatal(err) + } + + // After heal the meta file should be as expected. + if !reflect.DeepEqual(xlMetaPreHeal, xlMetaPostHeal) { + t.Fatal("HealObject failed") + } +}