Skip to content

Commit

Permalink
statemachine: update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
joelrebel committed May 4, 2023
1 parent f719c30 commit 42f8c53
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 87 deletions.
40 changes: 40 additions & 0 deletions internal/statemachine/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package statemachine

import (
sw "github.com/filanov/stateswitch"
)

// MockTaskHandler implements the TaskTransitioner interface
type MockTaskHandler struct{}

func (h *MockTaskHandler) Init(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) Query(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) Plan(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) ValidatePlan(_ sw.StateSwitch, _ sw.TransitionArgs) (bool, error) {
return true, nil
}

func (h *MockTaskHandler) Run(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) TaskFailed(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) TaskSuccessful(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}

func (h *MockTaskHandler) PublishStatus(_ sw.StateSwitch, _ sw.TransitionArgs) error {
return nil
}
141 changes: 54 additions & 87 deletions internal/statemachine/task_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// nolint
package statemachine

// this package gets its own fixtures to prevent import cycles.

import (
"context"
"net"
"testing"

Expand All @@ -14,40 +14,41 @@ import (
)

var (
firmware = []model.Firmware{
firmwares = []*model.Firmware{
{
Version: "2.6.6",
URL: "https://dl.dell.com/FOLDER08105057M/1/BIOS_C4FT0_WN64_2.6.6.EXE",
FileName: "BIOS_C4FT0_WN64_2.6.6.EXE",
Model: "r6515",
Checksum: "1ddcb3c3d0fc5925ef03a3dde768e9e245c579039dd958fc0f3a9c6368b6c5f4",
ComponentSlug: "bios",
Version: "2.6.6",
URL: "https://dl.dell.com/FOLDER08105057M/1/BIOS_C4FT0_WN64_2.6.6.EXE",
FileName: "BIOS_C4FT0_WN64_2.6.6.EXE",
Models: []string{"r6515"},
Checksum: "1ddcb3c3d0fc5925ef03a3dde768e9e245c579039dd958fc0f3a9c6368b6c5f4",
Component: "bios",
},
{
Version: "DL6R",
URL: "https://downloads.dell.com/FOLDER06303849M/1/Serial-ATA_Firmware_Y1P10_WN32_DL6R_A00.EXE",
FileName: "Serial-ATA_Firmware_Y1P10_WN32_DL6R_A00.EXE",
Model: "r6515",
Checksum: "4189d3cb123a781d09a4f568bb686b23c6d8e6b82038eba8222b91c380a25281",
ComponentSlug: "drive",
Version: "DL6R",
URL: "https://downloads.dell.com/FOLDER06303849M/1/Serial-ATA_Firmware_Y1P10_WN32_DL6R_A00.EXE",
FileName: "Serial-ATA_Firmware_Y1P10_WN32_DL6R_A00.EXE",
Models: []string{"r6515"},
Checksum: "4189d3cb123a781d09a4f568bb686b23c6d8e6b82038eba8222b91c380a25281",
Component: "drive",
},
}

device1 = uuid.New()
device2 = uuid.New()
asset1 = uuid.New()

devices = map[string]model.Device{
device1.String(): {
ID: device1,
asset2 = uuid.New()

assets = map[string]model.Asset{
asset1.String(): {
ID: asset1,
Vendor: "dell",
Model: "r6515",
BmcAddress: net.ParseIP("127.0.0.1"),
BmcUsername: "root",
BmcPassword: "hunter2",
},

device2.String(): {
ID: device2,
asset2.String(): {
ID: asset2,
Vendor: "dell",
Model: "r6515",
BmcAddress: net.ParseIP("127.0.0.2"),
Expand All @@ -57,36 +58,39 @@ var (
}
)

func newTaskFixture(status string) *model.Task {
task, _ := model.NewTask("", nil)
task.Status = string(status)
task.FirmwaresPlanned = firmware
task.Parameters.Device = devices[device1.String()]
func newTaskFixture(t *testing.T, state string) *model.Task {
t.Helper()

task := &model.Task{}
if err := task.SetState(sw.State(state)); err != nil {
t.Fatal(err)
}

task.InstallFirmwares = firmwares
task.Parameters.AssetID = asset1

return &task
return task
}

func Test_NewTaskStateMachine(t *testing.T) {
task, _ := model.NewTask("", nil)
task.Status = string(model.StateQueued)
task := &model.Task{}
task.Status = string(model.StatePending)

tests := []struct {
name string
task *model.Task
}{
{
"new task statemachine is created",
newTaskFixture(string(model.StateQueued)),
newTaskFixture(t, string(model.StatePending)),
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()

// transition handler implements the taskTransitioner methods to complete tasks
handler := &mockTaskHandler{}
m, err := NewTaskStateMachine(ctx, tc.task, handler)
handler := &MockTaskHandler{}
m, err := NewTaskStateMachine(handler)
if err != nil {
t.Fatal(err)
}
Expand All @@ -106,48 +110,48 @@ func Test_Transitions(t *testing.T) {
expectNoTransitionRuleError string
}{
{
"Queued to Active",
newTaskFixture(string(model.StateQueued)),
[]sw.TransitionType{TransitionTypePlan},
"Pending to Active",
newTaskFixture(t, string(model.StatePending)),
[]sw.TransitionType{TransitionTypeActive},
string(model.StateActive),
false,
"",
},
{
"Active to Success",
newTaskFixture(string(model.StateActive)),
newTaskFixture(t, string(model.StateActive)),
[]sw.TransitionType{TransitionTypeRun},
string(model.StateSuccess),
string(model.StateSucceeded),
false,
"",
},
{
"Queued to Success - run all transitions",
newTaskFixture(string(model.StateQueued)),
newTaskFixture(t, string(model.StatePending)),
[]sw.TransitionType{}, // with this not defined, the statemachine defaults to the configured transitions.
string(model.StateSuccess),
string(model.StateSucceeded),
false,
"",
},
{
"Queued to Failed",
newTaskFixture(string(model.StateActive)),
newTaskFixture(t, string(model.StateActive)),
[]sw.TransitionType{TransitionTypeTaskFail},
string(model.StateFailed),
true,
"",
},
{
"Active to Failed",
newTaskFixture(string(model.StateQueued)),
newTaskFixture(t, string(model.StatePending)),
[]sw.TransitionType{TransitionTypeTaskFail},
string(model.StateFailed),
true,
"",
},
{
"Success to Active fails - invalid transition",
newTaskFixture(string(model.StateQueued)),
newTaskFixture(t, string(model.StatePending)),
[]sw.TransitionType{TransitionTypeTaskSuccess},
string(model.StateFailed),
true,
Expand All @@ -157,13 +161,12 @@ func Test_Transitions(t *testing.T) {

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
// init task handler context
tctx := &HandlerContext{TaskID: tc.task.ID.String()}
handler := &mockTaskHandler{}
tctx := &HandlerContext{Task: tc.task}
handler := &MockTaskHandler{}

// init new state machine
m, err := NewTaskStateMachine(ctx, tc.task, handler)
m, err := NewTaskStateMachine(handler)
if err != nil {
t.Fatal(err)
}
Expand All @@ -174,55 +177,19 @@ func Test_Transitions(t *testing.T) {
}

// run transition
err = m.Run(ctx, tc.task, handler, tctx)
err = m.Run(tc.task, tctx)
if err != nil {
if !tc.expectError {
t.Fatal(err)
}
}

if tc.expectNoTransitionRuleError != "" {
assert.Equal(t, tc.task.Info, "no transition rule found for transition type 'plan' and state 'success': error in task transition")
assert.Equal(t, tc.task.Status, "no transition rule found for transition type 'plan' and state 'success': error in task transition")
}

assert.Equal(t, tc.expectedState, tc.task.Status)
assert.Equal(t, tc.expectedState, string(tc.task.State()))

})
}
}

// mockTaskHandler implements the TaskTransitioner interface
type mockTaskHandler struct{}

func (h *mockTaskHandler) Query(t sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

func (h *mockTaskHandler) Plan(t sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

// planFromFirmwareSet
func (h *mockTaskHandler) planFromFirmwareSet(tctx *HandlerContext, task *model.Task, device model.Device) error {
return nil
}

func (h *mockTaskHandler) ValidatePlan(t sw.StateSwitch, args sw.TransitionArgs) (bool, error) {
return true, nil
}

func (h *mockTaskHandler) Run(t sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

func (h *mockTaskHandler) TaskFailed(task sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

func (h *mockTaskHandler) TaskSuccessful(task sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

func (h *mockTaskHandler) PersistState(t sw.StateSwitch, args sw.TransitionArgs) error {
return nil
}

0 comments on commit 42f8c53

Please sign in to comment.