Fix format migration regression (#5668)

Migration regression got introduced in 9083bc152e
adding more unit tests to catch this scenario, we need to fix this by
re-writing the formats after the migration to 'V3'.

This bug only happens when a user is migrating directly from V1 to V3,
not from V1 to V2 and V2 to V3.

Added additional unit tests to cover these situations as well.

Fixes #5667
This commit is contained in:
Harshavardhana
2018-03-19 09:13:00 -07:00
committed by Nitish Tiwari
parent 049090126e
commit 2938e332ba
3 changed files with 153 additions and 2 deletions
+89 -2
View File
@@ -18,10 +18,12 @@ package cmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"reflect"
"testing"
"github.com/minio/minio/pkg/errors"
)
// Test get offline/online uuids.
@@ -74,6 +76,73 @@ func TestGetUUIDs(t *testing.T) {
}
}
// tests fixFormatXLV3 - fix format.json on all disks.
func TestFixFormatV3(t *testing.T) {
xlDirs, err := getRandomDisks(8)
if err != nil {
t.Fatal(err)
}
for _, xlDir := range xlDirs {
defer os.RemoveAll(xlDir)
}
endpoints := mustGetNewEndpointList(xlDirs...)
format := newFormatXLV3(1, 8)
formats := make([]*formatXLV3, 8)
for j := 0; j < 8; j++ {
newFormat := *format
newFormat.XL.This = format.XL.Sets[0][j]
formats[j] = &newFormat
}
if err = initFormatXLMetaVolume(endpoints, formats); err != nil {
t.Fatal(err)
}
formats[1] = nil
expThis := formats[2].XL.This
formats[2].XL.This = ""
if err := fixFormatXLV3(endpoints, formats); err != nil {
t.Fatal(err)
}
newFormats, errs := loadFormatXLAll(endpoints)
for _, err := range errs {
if err != nil && errors.Cause(err) != errUnformattedDisk {
t.Fatal(err)
}
}
gotThis := newFormats[2].XL.This
if expThis != gotThis {
t.Fatalf("expected uuid %s, got %s", expThis, gotThis)
}
}
// tests formatXLV3ThisEmpty conditions.
func TestFormatXLEmpty(t *testing.T) {
format := newFormatXLV3(1, 16)
formats := make([]*formatXLV3, 16)
for j := 0; j < 16; j++ {
newFormat := *format
newFormat.XL.This = format.XL.Sets[0][j]
formats[j] = &newFormat
}
// empty format to indicate disk not found, but this
// empty should return false.
formats[0] = nil
if ok := formatXLV3ThisEmpty(formats); ok {
t.Fatalf("expected value false, got %t", ok)
}
formats[2].XL.This = ""
if ok := formatXLV3ThisEmpty(formats); !ok {
t.Fatalf("expected value true, got %t", ok)
}
}
// Tests format xl get version.
func TestFormatXLGetVersion(t *testing.T) {
// Get test root.
@@ -201,7 +270,25 @@ func TestFormatXLMigrate(t *testing.T) {
t.Fatal(err)
}
if migratedVersion != formatXLVersionV3 {
t.Fatal(fmt.Sprintf("expected version: %s, got: %s", formatXLVersionV3, migratedVersion))
t.Fatalf("expected version: %s, got: %s", formatXLVersionV3, migratedVersion)
}
b, err = ioutil.ReadFile(pathJoin(rootPath, minioMetaBucket, formatConfigFile))
if err != nil {
t.Fatal(err)
}
formatV3 := &formatXLV3{}
if err = json.Unmarshal(b, formatV3); err != nil {
t.Fatal(err)
}
if formatV3.XL.This != m.XL.Disk {
t.Fatalf("expected disk uuid: %s, got: %s", m.XL.Disk, formatV3.XL.This)
}
if len(formatV3.XL.Sets) != 1 {
t.Fatalf("expected single set after migrating from v1 to v3, but found %d", len(formatV3.XL.Sets))
}
if !reflect.DeepEqual(formatV3.XL.Sets[0], m.XL.JBOD) {
t.Fatalf("expected disk uuid: %v, got: %v", m.XL.JBOD, formatV3.XL.Sets[0])
}
m = &formatXLV1{}