-
Notifications
You must be signed in to change notification settings - Fork 0
fix: a single failed drive no longer blanks a controller's device paths #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2143be3
858e4cf
8259e16
6e47606
cf64fb7
d7e2206
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,97 @@ | ||||||||||||||
| package megaraid | ||||||||||||||
|
|
||||||||||||||
| import ( | ||||||||||||||
| "testing" | ||||||||||||||
|
|
||||||||||||||
| "github.com/stretchr/testify/require" | ||||||||||||||
|
|
||||||||||||||
| "github.com/scality/raidmgmt/pkg/domain/entities/physicaldrive" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| // TestGetPaths pins the device/permanent path resolution for a logical volume, | ||||||||||||||
| // in particular that a degraded-but-online multi-drive volume whose udev | ||||||||||||||
| // by-id/wwn link is missing still yields its OS device path instead of failing | ||||||||||||||
| // discovery for the whole controller. | ||||||||||||||
| func TestGetPaths(t *testing.T) { | ||||||||||||||
| const wwnLink = "/dev/disk/by-id/wwn-0xabc123" | ||||||||||||||
|
|
||||||||||||||
| twoDrives := []*physicaldrive.PhysicalDrive{{}, {}} | ||||||||||||||
|
|
||||||||||||||
| tests := []struct { | ||||||||||||||
| name string | ||||||||||||||
| vdp *VDProperties | ||||||||||||||
| pdrives []*physicaldrive.PhysicalDrive | ||||||||||||||
| fileExists func(string) bool | ||||||||||||||
| evalSymlinks func(string) (string, error) | ||||||||||||||
| wantDevice string | ||||||||||||||
| wantPermanent string | ||||||||||||||
| wantErr bool | ||||||||||||||
| }{ | ||||||||||||||
| { | ||||||||||||||
| name: "wwn link present, os drive name reported", | ||||||||||||||
| vdp: &VDProperties{OSDriveName: "/dev/sdb", SCSINAAID: "abc123"}, | ||||||||||||||
| pdrives: twoDrives, | ||||||||||||||
| fileExists: func(string) bool { return true }, | ||||||||||||||
| wantDevice: "/dev/sdb", | ||||||||||||||
| wantPermanent: wwnLink, | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| name: "wwn link present, os drive name empty, resolved via symlink", | ||||||||||||||
| vdp: &VDProperties{OSDriveName: "", SCSINAAID: "abc123"}, | ||||||||||||||
| pdrives: twoDrives, | ||||||||||||||
| fileExists: func(string) bool { return true }, | ||||||||||||||
| evalSymlinks: func(string) (string, error) { return "/dev/sdb", nil }, | ||||||||||||||
| wantDevice: "/dev/sdb", | ||||||||||||||
| wantPermanent: wwnLink, | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| name: "degraded multi-drive volume, wwn link missing, keeps os drive name", | ||||||||||||||
| vdp: &VDProperties{OSDriveName: "/dev/sdb", SCSINAAID: "abc123"}, | ||||||||||||||
| pdrives: twoDrives, | ||||||||||||||
| fileExists: func(string) bool { return false }, | ||||||||||||||
| wantDevice: "/dev/sdb", | ||||||||||||||
| wantPermanent: "", | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| name: "multi-drive volume, no scsi naa id, keeps os drive name", | ||||||||||||||
| vdp: &VDProperties{OSDriveName: "/dev/sdb", SCSINAAID: ""}, | ||||||||||||||
| pdrives: twoDrives, | ||||||||||||||
| fileExists: func(string) bool { | ||||||||||||||
| t.Helper() | ||||||||||||||
| require.Fail(t, "FileExists must not be called for an empty SCSI NAA Id") | ||||||||||||||
| return false | ||||||||||||||
| }, | ||||||||||||||
| wantDevice: "/dev/sdb", | ||||||||||||||
| wantPermanent: "", | ||||||||||||||
| }, | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| origFileExists, origEvalSymlinks := CustomFileExists, CustomEvalSymlinks | ||||||||||||||
| defer func() { | ||||||||||||||
| CustomFileExists = origFileExists | ||||||||||||||
| CustomEvalSymlinks = origEvalSymlinks | ||||||||||||||
| }() | ||||||||||||||
|
|
||||||||||||||
| for _, tc := range tests { | ||||||||||||||
| t.Run(tc.name, func(t *testing.T) { | ||||||||||||||
| CustomFileExists = tc.fileExists | ||||||||||||||
| CustomEvalSymlinks = origEvalSymlinks | ||||||||||||||
|
|
||||||||||||||
| if tc.evalSymlinks != nil { | ||||||||||||||
| CustomEvalSymlinks = tc.evalSymlinks | ||||||||||||||
| } | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
— Claude Code |
||||||||||||||
|
|
||||||||||||||
| device, permanent, err := getPaths(tc.vdp, tc.pdrives) | ||||||||||||||
|
|
||||||||||||||
| if tc.wantErr { | ||||||||||||||
| require.Error(t, err) | ||||||||||||||
|
|
||||||||||||||
| return | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| require.NoError(t, err) | ||||||||||||||
| require.Equal(t, tc.wantDevice, device) | ||||||||||||||
| require.Equal(t, tc.wantPermanent, permanent) | ||||||||||||||
| }) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.