Skip to content

Commit

Permalink
Add tests for handleJobComplete
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Weinstock <[email protected]>
  • Loading branch information
jacobweinstock committed Sep 25, 2024
1 parent 12aedc8 commit d718bde
Show file tree
Hide file tree
Showing 2 changed files with 343 additions and 6 deletions.
8 changes: 3 additions & 5 deletions internal/deprecated/workflow/bootops.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ func handleExistingJob(ctx context.Context, cc client.Client, wf *v1alpha1.Workf

func handleJobCreation(ctx context.Context, cc client.Client, wf *v1alpha1.Workflow) (reconcile.Result, error) {
if wf.Status.Job.UID == "" && wf.Status.Job.ExistingJobDeleted {
// assumption is that at this point, if the job exists its because we created it already.
// requeue until the jobuid shows up.
existingJob := &rufio.Job{}
if err := cc.Get(ctx, client.ObjectKey{Name: fmt.Sprintf(bmcJobName, wf.Spec.HardwareRef), Namespace: wf.Namespace}, existingJob); err == nil {
wf.Status.Job.UID = existingJob.GetUID()
Expand All @@ -65,7 +63,7 @@ func handleJobCreation(ctx context.Context, cc client.Client, wf *v1alpha1.Workf
Message: fmt.Sprintf("error creating job: %v", err),
Time: &metav1.Time{Time: metav1.Now().UTC()},
})
return reconcile.Result{}, fmt.Errorf("error creating job.bmc.tinkerbell.org object for netbooting machine: %w", err)
return reconcile.Result{}, fmt.Errorf("error creating job.bmc.tinkerbell.org object: %w", err)

Check warning on line 66 in internal/deprecated/workflow/bootops.go

View check run for this annotation

Codecov / codecov/patch

internal/deprecated/workflow/bootops.go#L59-L66

Added lines #L59 - L66 were not covered by tests
}
wf.Status.SetCondition(v1alpha1.WorkflowCondition{
Type: v1alpha1.NetbootJobSetupComplete,
Expand All @@ -85,8 +83,8 @@ func handleJobComplete(ctx context.Context, cc client.Client, wf *v1alpha1.Workf
if !wf.Status.Job.Complete && wf.Status.Job.UID != "" && wf.Status.Job.ExistingJobDeleted {
existingJob := &rufio.Job{}
jobName := fmt.Sprintf(bmcJobName, wf.Spec.HardwareRef)
if gerr := cc.Get(ctx, client.ObjectKey{Name: jobName, Namespace: wf.Namespace}, existingJob); gerr != nil {
return reconcile.Result{}, fmt.Errorf("error getting one time netboot job: %w", gerr)
if err := cc.Get(ctx, client.ObjectKey{Name: jobName, Namespace: wf.Namespace}, existingJob); err != nil {
return reconcile.Result{}, fmt.Errorf("error getting one time netboot job: %w", err)

Check warning on line 87 in internal/deprecated/workflow/bootops.go

View check run for this annotation

Codecov / codecov/patch

internal/deprecated/workflow/bootops.go#L87

Added line #L87 was not covered by tests
}
if existingJob.HasCondition(rufio.JobFailed, rufio.ConditionTrue) {
wf.Status.SetCondition(v1alpha1.WorkflowCondition{
Expand Down
341 changes: 340 additions & 1 deletion internal/deprecated/workflow/bootops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@ package workflow
import (
"context"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
rufio "github.com/tinkerbell/rufio/api/v1alpha1"
"github.com/tinkerbell/tink/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

Expand Down Expand Up @@ -120,7 +126,6 @@ func TestHandleExistingJob(t *testing.T) {

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
//cc := GetFakeClientBuilder().Build()
runtimescheme := runtime.NewScheme()
rufio.AddToScheme(runtimescheme)
v1alpha1.AddToScheme(runtimescheme)
Expand All @@ -143,3 +148,337 @@ func TestHandleExistingJob(t *testing.T) {
})
}
}

func TestHandleJobCreation(t *testing.T) {
uid := uuid.NewUUID()
tests := map[string]struct {
workflow *v1alpha1.Workflow
wantWorkflow *v1alpha1.Workflow
wantResult reconcile.Result
job *rufio.Job
}{
"creation already done": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
UID: uid,
ExistingJobDeleted: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
UID: uid,
ExistingJobDeleted: true,
},
},
},
wantResult: reconcile.Result{},
},
"create new job": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{
HardwareRef: "machine1",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
ExistingJobDeleted: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{
HardwareRef: "machine1",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
ExistingJobDeleted: true,
},
Conditions: []v1alpha1.WorkflowCondition{
{Type: v1alpha1.NetbootJobSetupComplete, Status: v1.ConditionTrue, Reason: "Created", Message: "job created"},
},
},
},
wantResult: reconcile.Result{Requeue: true},
job: &rufio.Job{
ObjectMeta: v1.ObjectMeta{
Name: "tink-controller-machine1-one-time-netboot",
Namespace: "default",
ResourceVersion: "1",
Labels: map[string]string{
"tink-controller-auto-created": "true",
},
Annotations: map[string]string{
"tink-controller-auto-created": "true",
},
},
Spec: rufio.JobSpec{
MachineRef: rufio.MachineRef{
Name: "machine1",
Namespace: "default",
},
Tasks: []rufio.Action{
{PowerAction: ptr.To(rufio.PowerHardOff)},
{OneTimeBootDeviceAction: &rufio.OneTimeBootDeviceAction{Devices: []rufio.BootDevice{rufio.PXE}}},
{PowerAction: ptr.To(rufio.PowerOn)},
},
},
},
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
runtimescheme := runtime.NewScheme()
rufio.AddToScheme(runtimescheme)
v1alpha1.AddToScheme(runtimescheme)
clientBulider := GetFakeClientBuilder().WithScheme(runtimescheme)
clientBulider.WithRuntimeObjects(&v1alpha1.Hardware{
ObjectMeta: v1.ObjectMeta{
Name: "machine1",
Namespace: "default",
},
Spec: v1alpha1.HardwareSpec{
BMCRef: &corev1.TypedLocalObjectReference{Name: "machine1"},
},
})
cc := clientBulider.Build()

r, err := handleJobCreation(context.Background(), cc, tc.workflow)
if err != nil {
t.Fatalf("handleJobCreation() err = %v, want nil", err)
}
if diff := cmp.Diff(tc.wantResult, r); diff != "" {
t.Errorf("handleJobCreation() mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tc.wantWorkflow, tc.workflow, cmpopts.IgnoreFields(v1alpha1.WorkflowCondition{}, "Time")); diff != "" {
t.Errorf("handleJobCreation() mismatch (-want +got):\n%s", diff)
}
// check if the job is created
if tc.job != nil {
job := &rufio.Job{}
if err := cc.Get(context.Background(), client.ObjectKey{Name: tc.job.Name, Namespace: tc.job.Namespace}, job); err != nil {
t.Fatalf("handleJobCreation() job not created: %v", err)
}
if diff := cmp.Diff(tc.job, job); diff != "" {
t.Errorf("handleJobCreation() mismatch (-want +got):\n%s", diff)
}
}
})
}
}

func TestHandleJobComplete(t *testing.T) {
uid := uuid.NewUUID()
tests := map[string]struct {
workflow *v1alpha1.Workflow
wantWorkflow *v1alpha1.Workflow
wantResult reconcile.Result
job *rufio.Job
shouldError bool
}{
"status for existing job complete": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: true,
},
},
},
wantResult: reconcile.Result{},
},
"existing job not complete": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: false,
UID: uid,
ExistingJobDeleted: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: false,
UID: uid,
ExistingJobDeleted: true,
},
Conditions: []v1alpha1.WorkflowCondition{
{Type: v1alpha1.NetbootJobRunning, Status: v1.ConditionTrue, Reason: "Running", Message: "one time netboot job running"},
},
},
},
wantResult: reconcile.Result{RequeueAfter: 5 * time.Second},
job: &rufio.Job{
ObjectMeta: v1.ObjectMeta{
Name: "tink-controller-machine1-one-time-netboot",
Namespace: "default",
},
Status: rufio.JobStatus{
Conditions: []rufio.JobCondition{
{Type: rufio.JobRunning, Status: rufio.ConditionTrue},
},
},
},
},
"existing job failed": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: false,
UID: uid,
ExistingJobDeleted: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: false,
UID: uid,
ExistingJobDeleted: true,
},
Conditions: []v1alpha1.WorkflowCondition{
{Type: v1alpha1.NetbootJobFailed, Status: v1.ConditionTrue, Reason: "Error", Message: "one time netboot job failed"},
},
},
},
wantResult: reconcile.Result{},
job: &rufio.Job{
ObjectMeta: v1.ObjectMeta{
Name: "tink-controller-machine1-one-time-netboot",
Namespace: "default",
},
Status: rufio.JobStatus{
Conditions: []rufio.JobCondition{
{Type: rufio.JobFailed, Status: rufio.ConditionTrue},
},
},
},
shouldError: true,
},
"existing job completed": {
workflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
Job: v1alpha1.JobStatus{
Complete: false,
UID: uid,
ExistingJobDeleted: true,
},
},
},
wantWorkflow: &v1alpha1.Workflow{
ObjectMeta: v1.ObjectMeta{
Name: "workflow1",
Namespace: "default",
},
Spec: v1alpha1.WorkflowSpec{HardwareRef: "machine1"},
Status: v1alpha1.WorkflowStatus{
State: v1alpha1.WorkflowStatePending,
Job: v1alpha1.JobStatus{
Complete: true,
UID: uid,
ExistingJobDeleted: true,
},
Conditions: []v1alpha1.WorkflowCondition{
{Type: v1alpha1.NetbootJobComplete, Status: v1.ConditionTrue, Reason: "Complete", Message: "one time netboot job completed"},
},
},
},
wantResult: reconcile.Result{Requeue: true},
job: &rufio.Job{
ObjectMeta: v1.ObjectMeta{
Name: "tink-controller-machine1-one-time-netboot",
Namespace: "default",
},
Status: rufio.JobStatus{
Conditions: []rufio.JobCondition{
{Type: rufio.JobCompleted, Status: rufio.ConditionTrue},
},
},
},
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
runtimescheme := runtime.NewScheme()
rufio.AddToScheme(runtimescheme)
v1alpha1.AddToScheme(runtimescheme)
clientBulider := GetFakeClientBuilder().WithScheme(runtimescheme)
if tc.job != nil {
clientBulider.WithRuntimeObjects(tc.job)
}
cc := clientBulider.Build()

r, err := handleJobComplete(context.Background(), cc, tc.workflow)
if err != nil && !tc.shouldError {
t.Fatalf("handleJobComplete() err = %v, want nil", err)
}
if diff := cmp.Diff(tc.wantResult, r); diff != "" {
t.Errorf("result mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tc.wantWorkflow, tc.workflow, cmpopts.IgnoreFields(v1alpha1.WorkflowCondition{}, "Time")); diff != "" {
t.Errorf("workflow mismatch (-want +got):\n%s", diff)
}
})
}
}

0 comments on commit d718bde

Please sign in to comment.