mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-17 04:36:50 +00:00
* wdclient: keep the location of a volume reported added and removed at once A volume moved between a server's disks arrives in both lists of one message, and the server still has it. Additions were applied before removals, so the removal won and the client was left with no location for a volume that never went anywhere. Reordering would swap the bug for a window where the volume resolves nowhere, since the two updates take the lock separately. Skip the removal instead, so the order the lists are applied in stops mattering. * wdclient: build each ec update explicitly in the move test Reusing one response object and adding the deletion to it left the overlap the test turns on implicit, and reading it as a delete-only update is the natural mistake.
81 lines
2.8 KiB
Go
81 lines
2.8 KiB
Go
package wdclient
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
|
)
|
|
|
|
func moveClient() *MasterClient {
|
|
return &MasterClient{vidMapClient: newVidMapClient(nil, "", 0)}
|
|
}
|
|
|
|
func moveResponse(newVids, deletedVids []uint32) *master_pb.KeepConnectedResponse {
|
|
return &master_pb.KeepConnectedResponse{VolumeLocation: &master_pb.VolumeLocation{
|
|
Url: "server:8080", PublicUrl: "server:8080", NewVids: newVids, DeletedVids: deletedVids,
|
|
}}
|
|
}
|
|
|
|
// A volume moved between a server's disks arrives added and removed at once,
|
|
// and the server still has it.
|
|
func TestMovedVolumeKeepsItsLocation(t *testing.T) {
|
|
mc := moveClient()
|
|
mc.updateVidMap(moveResponse([]uint32{1}, nil))
|
|
mc.updateVidMap(moveResponse([]uint32{1}, []uint32{1}))
|
|
|
|
locations, found := mc.GetLocations(1)
|
|
if !found || len(locations) != 1 {
|
|
t.Errorf("a volume that moved between its server's disks lost its location: found=%v %v", found, locations)
|
|
}
|
|
}
|
|
|
|
func TestRemovedVolumeLosesItsLocation(t *testing.T) {
|
|
mc := moveClient()
|
|
mc.updateVidMap(moveResponse([]uint32{1}, nil))
|
|
mc.updateVidMap(moveResponse(nil, []uint32{1}))
|
|
|
|
if locations, found := mc.GetLocations(1); found && len(locations) > 0 {
|
|
t.Errorf("a volume that left the server kept its location: %v", locations)
|
|
}
|
|
}
|
|
|
|
// Removals of other volumes in the same message must still apply.
|
|
func TestRemovalsAlongsideAMoveStillApply(t *testing.T) {
|
|
mc := moveClient()
|
|
mc.updateVidMap(moveResponse([]uint32{1, 2}, nil))
|
|
mc.updateVidMap(moveResponse([]uint32{1}, []uint32{1, 2}))
|
|
|
|
if locations, found := mc.GetLocations(1); !found || len(locations) != 1 {
|
|
t.Errorf("the moved volume lost its location: found=%v %v", found, locations)
|
|
}
|
|
if locations, found := mc.GetLocations(2); found && len(locations) > 0 {
|
|
t.Errorf("a volume that left the server kept its location: %v", locations)
|
|
}
|
|
}
|
|
|
|
func moveEcResponse(newEcVids, deletedEcVids []uint32) *master_pb.KeepConnectedResponse {
|
|
return &master_pb.KeepConnectedResponse{VolumeLocation: &master_pb.VolumeLocation{
|
|
Url: "server:8080", PublicUrl: "server:8080", NewEcVids: newEcVids, DeletedEcVids: deletedEcVids,
|
|
}}
|
|
}
|
|
|
|
func TestEcVolumeMovedKeepsItsLocation(t *testing.T) {
|
|
mc := moveClient()
|
|
mc.updateVidMap(moveEcResponse([]uint32{7}, nil))
|
|
mc.updateVidMap(moveEcResponse([]uint32{7}, []uint32{7}))
|
|
|
|
if locations, found := mc.GetLocations(7); !found || len(locations) != 1 {
|
|
t.Errorf("an ec volume reported both ways lost its location: found=%v %v", found, locations)
|
|
}
|
|
}
|
|
|
|
func TestEcVolumeRemovedLosesItsLocation(t *testing.T) {
|
|
mc := moveClient()
|
|
mc.updateVidMap(moveEcResponse([]uint32{7}, nil))
|
|
mc.updateVidMap(moveEcResponse(nil, []uint32{7}))
|
|
|
|
if locations, found := mc.GetLocations(7); found && len(locations) > 0 {
|
|
t.Errorf("an ec volume that left the server kept its location: %v", locations)
|
|
}
|
|
}
|