Skip to content

Commit

Permalink
Fix a race condition in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
atrubachev committed Apr 17, 2020
1 parent 7a120bf commit 02f39ef
Show file tree
Hide file tree
Showing 9 changed files with 737 additions and 808 deletions.
15 changes: 13 additions & 2 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,45 @@ import (
var (
// ErrLoginFailed is returned when we fail to login to a bmc
ErrLoginFailed = errors.New("failed to login")

// ErrBiosNotFound is returned when we are not able to find the server bios version
ErrBiosNotFound = errors.New("bios version not found")

// ErrVendorUnknown is returned when we are unable to identify the redfish vendor
ErrVendorUnknown = errors.New("unable to identify the vendor")

// ErrInvalidSerial is returned when the serial number for the device is invalid
ErrInvalidSerial = errors.New("unable to find the serial number")

// ErrPageNotFound is used to inform the http request that we couldn't find the expected page and/or endpoint
ErrPageNotFound = errors.New("requested page couldn't be found in the server")

// ErrRedFishNotSupported is returned when redfish isn't supported by the vendor
ErrRedFishNotSupported = errors.New("redfish not supported")

// ErrUnableToReadData is returned when we fail to read data from a chassis or bmc
ErrUnableToReadData = errors.New("unable to read data from this device")

// ErrVendorNotSupported is returned when we are able to identify a vendor but we won't support it
ErrVendorNotSupported = errors.New("vendor not supported")

// ErrUnableToGetSessionToken is returned when we are unable to retrieve ST2 which is required to set configuration parameters
ErrUnableToGetSessionToken = errors.New("unable to get ST2 session token")

// Err500 is returned when we receive a 500 response from an endpoint.
Err500 = errors.New("we've received 500 calling this endpoint")

// ErrNotImplemented is returned for not implemented methods called
ErrNotImplemented = errors.New("this feature hasn't been implemented yet")

// ErrFeatureUnavailable is returned for features not available/supported.
ErrFeatureUnavailable = errors.New("this feature isn't supported/available for this hardware")

// ErrIdracMaxSessionsReached indicates the bmc has reached the max number of login sessions.
ErrIdracMaxSessionsReached = errors.New("The maximum number of user sessions is reached")
ErrIdracMaxSessionsReached = errors.New("the maximum number of user sessions is reached")

// Err401Redfish indicates auth failure
Err401Redfish = errors.New("Redfish authorization failed")
Err401Redfish = errors.New("redfish authorization failed")

// ErrDeviceNotMatched is the error returned when the device was not a type it was probed for
ErrDeviceNotMatched = errors.New("the vendor device did not match the probe")
Expand Down
205 changes: 76 additions & 129 deletions providers/dell/idrac8/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import (
"github.com/bmc-toolbox/bmclib/sshmock"
)

const (
sshUsername = "super"
sshPassword = "test"
)

var (
sshServer *sshmock.Server
sshAnswers = map[string][]byte{
"racadm serveraction hardreset": []byte(`Server power operation successful`),
"racadm racreset hard": []byte(`RAC reset operation initiated successfully. It may take a few
Expand Down Expand Up @@ -39,144 +43,87 @@ var (
}
)

func setupSSH() (bmc *IDrac8, err error) {
username := "super"
password := "test"

sshServer, err = sshmock.New(sshAnswers, true)
func setupBMC() (func(), *IDrac8, error) {
ssh, err := sshmock.New(sshAnswers)
if err != nil {
return bmc, err
return nil, nil, err
}
address := sshServer.Address()

bmc, err = New(address, username, password)
tearDown, address, err := ssh.ListenAndServe()
if err != nil {
return bmc, err
return nil, nil, err
}

return bmc, err
}

func tearDownSSH() {
sshServer.Close()
}

func TestIDracPowerCycle(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
bmc, err := New(address, sshUsername, sshPassword)
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
tearDown()
return nil, nil, err
}

answer, err := bmc.PowerCycle()
if err != nil {
t.Fatalf("Found errors calling bmc.PowerCycle %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
return tearDown, bmc, err
}

func TestIDracPowerCycleBmc(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
func Test_IDrac8(t *testing.T) {
tearDown, bmc, err := setupBMC()
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
t.Fatalf("failed to setup BMC: %v", err)
}
defer tearDown()

tests := []struct {
name string
bmcMethod func() (bool, error)
want bool
wantErr bool
}{
{
name: "PowerCycle",
bmcMethod: bmc.PowerCycle,
want: true,
wantErr: false,
},
{
name: "PowerCycleBmc",
bmcMethod: bmc.PowerCycleBmc,
want: true,
wantErr: false,
},
{
name: "PowerOn",
bmcMethod: bmc.PowerOn,
want: true,
wantErr: false,
},
{
name: "PowerOff",
bmcMethod: bmc.PowerOff,
want: true,
wantErr: false,
},
{
name: "PxeOnce",
bmcMethod: bmc.PxeOnce,
want: true,
wantErr: false,
},
{
name: "IsOn",
bmcMethod: bmc.IsOn,
want: true,
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.bmcMethod()

if (err != nil) != tt.wantErr {
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("got = %v, want %v", got, tt.want)
}
})
}

answer, err := bmc.PowerCycleBmc()
if err != nil {
t.Fatalf("Found errors calling bmc.PowerCycleBmc %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
}

func TestIDracPowerOn(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
}

answer, err := bmc.PowerOn()
if err != nil {
t.Fatalf("Found errors calling bmc.PowerOn %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
}

func TestIDracPowerOff(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
}

answer, err := bmc.PowerOff()
if err != nil {
t.Fatalf("Found errors calling bmc.PowerOff %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
}

func TestIDracPxeOnce(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
}

answer, err := bmc.PxeOnce()
if err != nil {
t.Fatalf("Found errors calling bmc.PxeOnce %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
}

func TestIDracIsOn(t *testing.T) {
expectedAnswer := true

bmc, err := setupSSH()
if err != nil {
t.Fatalf("Found errors during the test setup %v", err)
}

answer, err := bmc.IsOn()
if err != nil {
t.Fatalf("Found errors calling bmc.IsOn %v", err)
}

if answer != expectedAnswer {
t.Errorf("Expected answer %v: found %v", expectedAnswer, answer)
}

tearDownSSH()
}
Loading

0 comments on commit 02f39ef

Please sign in to comment.