Browse Source
Implement full scrubbing for regular volumes (#8254)
Implement full scrubbing for regular volumes (#8254)
Implement full scrubbing for regular volumes.pull/8342/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 187 additions and 38 deletions
-
16weed/server/volume_grpc_scrub.go
-
3weed/shell/command_volume_scrub.go
-
2weed/storage/needle/needle_read.go
-
BINweed/storage/test_files/bitrot_volume.dat
-
BINweed/storage/test_files/bitrot_volume.idx
-
BINweed/storage/test_files/healthy_volume.dat
-
BINweed/storage/test_files/healthy_volume.idx
-
124weed/storage/volume_checking.go
-
80weed/storage/volume_checking_test.go
@ -0,0 +1,80 @@ |
|||
package storage |
|||
|
|||
import ( |
|||
"fmt" |
|||
"os" |
|||
"reflect" |
|||
"testing" |
|||
|
|||
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb" |
|||
"github.com/seaweedfs/seaweedfs/weed/storage/backend" |
|||
"github.com/seaweedfs/seaweedfs/weed/storage/needle" |
|||
) |
|||
|
|||
func TestScrubVolumeData(t *testing.T) { |
|||
testCases := []struct { |
|||
name string |
|||
dataPath string |
|||
indexPath string |
|||
version needle.Version |
|||
want int64 |
|||
wantErrs []error |
|||
}{ |
|||
{ |
|||
name: "healthy volume", |
|||
dataPath: "./test_files/healthy_volume.dat", |
|||
indexPath: "./test_files/healthy_volume.idx", |
|||
version: needle.Version3, |
|||
want: 27, |
|||
wantErrs: []error{}, |
|||
}, |
|||
{ |
|||
name: "bitrot volume", |
|||
dataPath: "./test_files/bitrot_volume.dat", |
|||
indexPath: "./test_files/bitrot_volume.idx", |
|||
version: needle.Version3, |
|||
want: 27, |
|||
wantErrs: []error{ |
|||
fmt.Errorf("needle 3 on volume 0: invalid CRC for needle 3 (got 0b243a0d, want 4af853fb), data on disk corrupted"), |
|||
fmt.Errorf("needle 48 on volume 0: invalid CRC for needle 30 (got 3c40e8d5, want 5077fea1), data on disk corrupted"), |
|||
fmt.Errorf("data file size for volume 0 (942864) doesn't match the size for 27 needles read (942856)"), |
|||
}, |
|||
}, |
|||
} |
|||
|
|||
for _, tc := range testCases { |
|||
t.Run(tc.name, func(t *testing.T) { |
|||
datFile, err := os.OpenFile(tc.dataPath, os.O_RDONLY, 0) |
|||
if err != nil { |
|||
t.Fatalf("failed to open data file: %v", err) |
|||
} |
|||
defer datFile.Close() |
|||
|
|||
idxFile, err := os.OpenFile(tc.indexPath, os.O_RDONLY, 0) |
|||
if err != nil { |
|||
t.Fatalf("failed to open index file: %v", err) |
|||
} |
|||
defer idxFile.Close() |
|||
|
|||
idxStat, err := idxFile.Stat() |
|||
if err != nil { |
|||
t.Fatalf("failed to stat index file: %v", err) |
|||
} |
|||
|
|||
v := Volume{ |
|||
volumeInfo: &volume_server_pb.VolumeInfo{ |
|||
Version: uint32(tc.version), |
|||
}, |
|||
} |
|||
|
|||
got, gotErrs := v.scrubVolumeData(backend.NewDiskFile(datFile), idxFile, idxStat.Size()) |
|||
|
|||
if got != tc.want { |
|||
t.Errorf("expected %d files processed, got %d", tc.want, got) |
|||
} |
|||
if !reflect.DeepEqual(gotErrs, tc.wantErrs) { |
|||
t.Errorf("expected errors %v, got %v", tc.wantErrs, gotErrs) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue