airshipctl/pkg/remote/redfish/client_test.go
Kostiantyn Kalynovskyi decc12b0a9 Move remotedirect method to remote interface
Please note that this is first commit in series and in next commits
remote/remote_direct* files will be remove completely, so if you
have any comments that address issues in these files, keep in mind
that they will be remove in next patchsets.

Change-Id: I52e9b8438a4f8e1a2395cbe90238b9cb654772d4
2021-01-21 23:09:54 +00:00

988 lines
33 KiB
Go

/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package redfish
import (
"context"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
redfishMocks "opendev.org/airship/go-redfish/api/mocks"
redfishClient "opendev.org/airship/go-redfish/client"
"opendev.org/airship/airshipctl/pkg/remote/power"
testutil "opendev.org/airship/airshipctl/testutil/redfishutils/helpers"
)
const (
nodeID = "System.Embedded.1"
isoPath = "http://localhost:8099/ubuntu-focal.iso"
redfishURL = "redfish+https://localhost:2224/Systems/System.Embedded.1"
systemActionRetries = 1
systemRebootDelay = 0
)
func TestNewClient(t *testing.T) {
c, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
assert.NotNil(t, c)
}
func TestNewClientInterface(t *testing.T) {
c, err := ClientFactory(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
assert.NotNil(t, c)
}
func TestNewClientDefaultValues(t *testing.T) {
sysActRetr := 111
sysRebDel := 999
c, err := NewClient(redfishURL, false, false, "", "", sysActRetr, sysRebDel)
assert.Equal(t, c.systemActionRetries, sysActRetr)
assert.Equal(t, c.systemRebootDelay, sysRebDel)
assert.NoError(t, err)
}
func TestNewClientMissingSystemID(t *testing.T) {
badURL := "redfish+https://localhost:2224"
_, err := NewClient(badURL, false, false, "", "", systemActionRetries, systemRebootDelay)
_, ok := err.(ErrRedfishMissingConfig)
assert.True(t, ok)
}
func TestNewClientNoRedfishMarking(t *testing.T) {
url := "https://localhost:2224/Systems/System.Embedded.1"
_, err := NewClient(url, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
}
func TestNewClientEmptyRedfishURL(t *testing.T) {
// Redfish URL cannot be empty when creating a client.
_, err := NewClient("", false, false, "", "", systemActionRetries, systemRebootDelay)
assert.Error(t, err)
}
func TestEjectVirtualMedia(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries+1, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mark CD and DVD test media as inserted
inserted := true
testMediaCD := testutil.GetVirtualMedia([]string{"CD"})
testMediaCD.Inserted = &inserted
testMediaDVD := testutil.GetVirtualMedia([]string{"DVD"})
testMediaDVD.Inserted = &inserted
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil).Times(1)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd", "DVD", "Floppy"}), httpResp, nil)
// Eject CD
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMediaCD, httpResp, nil)
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Times(1).
Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"Cd"}), httpResp, nil)
// Eject DVD and simulate two retries
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "DVD").Times(1).
Return(testMediaDVD, httpResp, nil)
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "DVD", mock.Anything).Times(1).
Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "DVD").Times(1).
Return(testMediaDVD, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "DVD").Times(1).
Return(testutil.GetVirtualMedia([]string{"DVD"}), httpResp, nil)
// Floppy is not inserted, so it is not ejected
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Floppy").Times(1).
Return(testutil.GetVirtualMedia([]string{"Floppy"}), httpResp, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.EjectVirtualMedia(ctx)
assert.NoError(t, err)
}
func TestEjectVirtualMediaRetriesExceeded(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mark test media as inserted
inserted := true
testMedia := testutil.GetVirtualMedia([]string{"CD"})
testMedia.Inserted = &inserted
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").
Return(testMedia, httpResp, nil)
// Verify retry logic
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).
Return(redfishClient.RedfishError{}, httpResp, nil)
// Media still inserted on retry. Since retries are 1, this causes failure.
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").
Return(testMedia, httpResp, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.EjectVirtualMedia(ctx)
_, ok := err.(ErrOperationRetriesExceeded)
assert.True(t, ok)
}
func TestRebootSystem(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mock redfish shutdown and status requests
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
httpResp := &http.Response{StatusCode: 200}
m.On("ResetSystem", ctx, client.nodeID, resetReq).Times(1).Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetSystem", ctx, client.nodeID).Times(1).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_OFF}, httpResp, nil)
// Mock redfish startup and status requests
resetReq.ResetType = redfishClient.RESETTYPE_ON
m.On("ResetSystem", ctx, client.nodeID, resetReq).Times(1).Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetSystem", ctx, client.nodeID).Times(1).
Return(redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_ON}, httpResp, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.RebootSystem(ctx)
assert.NoError(t, err)
}
func TestRebootSystemShutdownError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
// Mock redfish shutdown request for failure
m.On("ResetSystem", ctx, client.nodeID, resetReq).Times(1).Return(redfishClient.RedfishError{},
&http.Response{StatusCode: 401}, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.RebootSystem(ctx)
_, ok := err.(ErrRedfishClient)
assert.True(t, ok)
}
func TestRebootSystemStartupError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
// Mock redfish shutdown request
m.On("ResetSystem", ctx, client.nodeID, resetReq).Times(1).Return(redfishClient.RedfishError{},
&http.Response{StatusCode: 200}, nil)
m.On("GetSystem", ctx, client.nodeID).Times(1).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_OFF},
&http.Response{StatusCode: 200}, nil)
resetOnReq := redfishClient.ResetRequestBody{}
resetOnReq.ResetType = redfishClient.RESETTYPE_ON
// Mock redfish startup request for failure
m.On("ResetSystem", ctx, client.nodeID, resetOnReq).Times(1).Return(redfishClient.RedfishError{},
&http.Response{StatusCode: 401}, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.RebootSystem(ctx)
_, ok := err.(ErrRedfishClient)
assert.True(t, ok)
}
func TestRebootSystemTimeout(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
m.On("ResetSystem", ctx, client.nodeID, resetReq).
Times(1).
Return(redfishClient.RedfishError{}, &http.Response{StatusCode: 200}, nil)
m.On("GetSystem", ctx, client.nodeID).
Return(redfishClient.ComputerSystem{}, &http.Response{StatusCode: 200}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.RebootSystem(ctx)
assert.Error(t, err)
}
func TestSetBootSourceByTypeGetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mock redfish get system request
m.On("GetSystem", ctx, client.NodeID()).Times(1).Return(redfishClient.ComputerSystem{},
&http.Response{StatusCode: 500}, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetBootSourceByType(ctx)
assert.Error(t, err)
}
func TestSetBootSourceByTypeSetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
m.On("SetSystem", ctx, client.nodeID, mock.Anything).Times(1).Return(
redfishClient.ComputerSystem{}, &http.Response{StatusCode: 401}, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetBootSourceByType(ctx)
assert.Error(t, err)
}
func TestSetBootSourceByTypeBootSourceUnavailable(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
client.nodeID = nodeID
invalidSystem := testutil.GetTestSystem()
invalidSystem.Boot.BootSourceOverrideTargetRedfishAllowableValues = []redfishClient.BootSource{
redfishClient.BOOTSOURCE_HDD,
redfishClient.BOOTSOURCE_PXE,
}
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(invalidSystem, httpResp, nil)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetBootSourceByType(ctx)
_, ok := err.(ErrRedfishClient)
assert.True(t, ok)
}
func TestSetVirtualMediaEjectExistingMedia(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mark test media as inserted
inserted := true
testMedia := testutil.GetVirtualMedia([]string{"CD"})
testMedia.Inserted = &inserted
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil)
// Eject Media calls
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMedia, httpResp, nil)
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Times(1).
Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
// Insert media calls
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
m.On("InsertVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Return(
redfishClient.RedfishError{}, httpResp, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetVirtualMedia(ctx, isoPath)
assert.NoError(t, err)
}
func TestSetVirtualMediaEjectExistingMediaFailure(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
// Mark test media as inserted
inserted := true
testMedia := testutil.GetVirtualMedia([]string{"CD"})
testMedia.Inserted = &inserted
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil)
// Eject Media calls
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMedia, httpResp, nil)
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Times(1).
Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMedia, httpResp, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetVirtualMedia(ctx, isoPath)
assert.Error(t, err)
}
func TestSetVirtualMediaGetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
client.nodeID = nodeID
// Mock redfish get system request
m.On("GetSystem", ctx, client.nodeID).Times(1).Return(redfishClient.ComputerSystem{},
nil, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetVirtualMedia(ctx, isoPath)
assert.Error(t, err)
}
func TestSetVirtualMediaInsertVirtualMediaError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
client.nodeID = nodeID
httpResp := &http.Response{StatusCode: 200}
m.On("GetSystem", ctx, client.nodeID).Return(testutil.GetTestSystem(), httpResp, nil)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
// Insert media calls
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).Times(1).
Return(testutil.GetMediaCollection([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"CD"}), httpResp, nil)
m.On("InsertVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Return(
redfishClient.RedfishError{}, &http.Response{StatusCode: 500}, redfishClient.GenericOpenAPIError{})
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SetVirtualMedia(ctx, isoPath)
_, ok := err.(ErrRedfishClient)
assert.True(t, ok)
}
func TestSystemPowerOff(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("ResetSystem", ctx, client.nodeID, mock.Anything).Return(
redfishClient.RedfishError{},
&http.Response{StatusCode: 200}, nil)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_ON},
&http.Response{StatusCode: 200}, nil).Times(1)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_OFF},
&http.Response{StatusCode: 200}, nil).Times(1)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SystemPowerOff(ctx)
assert.NoError(t, err)
}
func TestSystemPowerOffResetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("ResetSystem", ctx, client.nodeID, mock.Anything).Return(
redfishClient.RedfishError{},
&http.Response{StatusCode: 500}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SystemPowerOff(ctx)
assert.Error(t, err)
}
func TestSystemPowerOn(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("ResetSystem", ctx, client.nodeID, mock.Anything).Return(
redfishClient.RedfishError{},
&http.Response{StatusCode: 200}, nil)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_OFF},
&http.Response{StatusCode: 200}, nil).Times(1)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_ON},
&http.Response{StatusCode: 200}, nil).Times(1)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SystemPowerOn(ctx)
assert.NoError(t, err)
}
func TestSystemPowerOnResetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("ResetSystem", ctx, client.nodeID, mock.Anything).Return(
redfishClient.RedfishError{},
&http.Response{StatusCode: 500}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.SystemPowerOn(ctx)
assert.Error(t, err)
}
func TestSystemPowerStatusUnknown(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
var unknownState redfishClient.PowerState = "unknown"
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: unknownState},
&http.Response{StatusCode: 200},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
status, err := client.SystemPowerStatus(ctx)
require.NoError(t, err)
assert.Equal(t, power.StatusUnknown, status)
}
func TestSystemPowerStatusOn(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
client.nodeID = nodeID
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_ON},
&http.Response{StatusCode: 200},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
status, err := client.SystemPowerStatus(ctx)
require.NoError(t, err)
assert.Equal(t, power.StatusOn, status)
}
func TestSystemPowerStatusOff(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_OFF},
&http.Response{StatusCode: 200},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
status, err := client.SystemPowerStatus(ctx)
require.NoError(t, err)
assert.Equal(t, power.StatusOff, status)
}
func TestSystemPowerStatusPoweringOn(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_POWERING_ON},
&http.Response{StatusCode: 200},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
status, err := client.SystemPowerStatus(ctx)
require.NoError(t, err)
assert.Equal(t, power.StatusPoweringOn, status)
}
func TestSystemPowerStatusPoweringOff(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{PowerState: redfishClient.POWERSTATE_POWERING_OFF},
&http.Response{StatusCode: 200},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
status, err := client.SystemPowerStatus(ctx)
require.NoError(t, err)
assert.Equal(t, power.StatusPoweringOff, status)
}
func TestSystemPowerStatusGetSystemError(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.nodeID = nodeID
ctx := SetAuth(context.Background(), "", "")
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{},
&http.Response{StatusCode: 500},
redfishClient.GenericOpenAPIError{})
client.RedfishAPI = m
_, err = client.SystemPowerStatus(ctx)
assert.Error(t, err)
}
func TestWaitForPowerStateGetSystemFailed(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{}, &http.Response{StatusCode: 500}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.waitForPowerState(ctx, redfishClient.POWERSTATE_OFF)
assert.Error(t, err)
}
func TestWaitForPowerStateNoRetries(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_OFF,
}, &http.Response{StatusCode: 200}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.waitForPowerState(ctx, redfishClient.POWERSTATE_OFF)
assert.NoError(t, err)
}
func TestWaitForPowerStateWithRetries(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_ON,
}, &http.Response{StatusCode: 200}, nil).Times(1)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_OFF,
}, &http.Response{StatusCode: 200}, nil).Times(1)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.waitForPowerState(ctx, redfishClient.POWERSTATE_OFF)
assert.NoError(t, err)
}
func TestWaitForPowerStateRetriesExceeded(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_OFF
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_ON,
}, &http.Response{StatusCode: 200}, nil)
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_ON,
}, &http.Response{StatusCode: 200}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.waitForPowerState(ctx, redfishClient.POWERSTATE_OFF)
assert.Error(t, err)
}
func TestWaitForPowerStateDifferentPowerState(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
defer m.AssertExpectations(t)
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
assert.NoError(t, err)
ctx := SetAuth(context.Background(), "", "")
resetReq := redfishClient.ResetRequestBody{}
resetReq.ResetType = redfishClient.RESETTYPE_FORCE_ON
m.On("GetSystem", ctx, client.nodeID).Return(
redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_ON,
}, &http.Response{StatusCode: 200}, nil)
// Replace normal API client with mocked API client
client.RedfishAPI = m
// Mock out the Sleep function so we don't have to wait on it
client.Sleep = func(_ time.Duration) {}
err = client.waitForPowerState(ctx, redfishClient.POWERSTATE_ON)
assert.NoError(t, err)
}
func TestRemoteDirect(t *testing.T) {
m := &redfishMocks.RedfishAPI{}
client, err := NewClient(redfishURL, false, false, "", "", systemActionRetries, systemRebootDelay)
require.NoError(t, err)
client.RedfishAPI = m
inserted := true
testMediaCD := testutil.GetVirtualMedia([]string{"CD"})
testMediaCD.Inserted = &inserted
resetReq := redfishClient.ResetRequestBody{
ResetType: redfishClient.RESETTYPE_FORCE_OFF,
}
httpResp := &http.Response{StatusCode: 200}
system := redfishClient.ComputerSystem{
PowerState: redfishClient.POWERSTATE_ON,
Links: redfishClient.SystemLinks{
ManagedBy: []redfishClient.IdRef{
{OdataId: testutil.ManagerID},
},
},
Boot: redfishClient.Boot{
BootSourceOverrideTargetRedfishAllowableValues: []redfishClient.BootSource{
redfishClient.BOOTSOURCE_CD,
},
}}
ctx := SetAuth(context.Background(), "", "")
m.On("GetSystem", ctx, client.nodeID).Return(system, httpResp, nil).Times(6)
m.On("ListManagerVirtualMedia", ctx, testutil.ManagerID).
Return(testutil.GetMediaCollection([]string{"Cd", "DVD", "Floppy"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMediaCD, httpResp, nil)
m.On("EjectVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Times(1).
Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testutil.GetVirtualMedia([]string{"Cd"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "DVD").Times(1).
Return(testutil.GetVirtualMedia([]string{"DVD"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Floppy").Times(1).
Return(testutil.GetVirtualMedia([]string{"Floppy"}), httpResp, nil)
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMediaCD, httpResp, nil)
m.On("InsertVirtualMedia", ctx, testutil.ManagerID, "Cd", mock.Anything).Return(
redfishClient.RedfishError{}, httpResp, redfishClient.GenericOpenAPIError{})
m.On("GetManagerVirtualMedia", ctx, testutil.ManagerID, "Cd").Times(1).
Return(testMediaCD, httpResp, nil)
m.On("SetSystem", ctx, client.nodeID, mock.Anything).Times(1).Return(
redfishClient.ComputerSystem{}, httpResp, nil)
m.On("ResetSystem", ctx, client.nodeID, resetReq).Times(1).Return(redfishClient.RedfishError{}, httpResp, nil)
offSystem := system
offSystem.PowerState = redfishClient.POWERSTATE_OFF
m.On("GetSystem", ctx, client.nodeID).Return(offSystem, httpResp, nil).Times(1)
m.On("ResetSystem", ctx, client.nodeID, redfishClient.ResetRequestBody{
ResetType: redfishClient.RESETTYPE_ON,
}).Times(1).Return(redfishClient.RedfishError{}, httpResp, nil)
m.On("GetSystem", ctx, client.nodeID).Return(system, httpResp, nil).Times(1)
err = client.RemoteDirect(ctx, "http://some-url")
assert.NoError(t, err)
}