github.com/kubevela/workflow@v0.6.0/pkg/tasks/builtin/step_group_test.go (about) 1 package builtin 2 3 import ( 4 "context" 5 "encoding/json" 6 "testing" 7 8 "github.com/kubevela/workflow/pkg/cue/process" 9 "github.com/stretchr/testify/require" 10 "sigs.k8s.io/yaml" 11 12 monitorContext "github.com/kubevela/pkg/monitor/context" 13 "github.com/kubevela/workflow/api/v1alpha1" 14 wfContext "github.com/kubevela/workflow/pkg/context" 15 "github.com/kubevela/workflow/pkg/types" 16 corev1 "k8s.io/api/core/v1" 17 ) 18 19 type testEngine struct { 20 stepStatus v1alpha1.WorkflowStepStatus 21 operation *types.Operation 22 } 23 24 func (e *testEngine) Run(ctx monitorContext.Context, taskRunners []types.TaskRunner, dag bool) error { 25 return nil 26 } 27 28 func (e *testEngine) GetStepStatus(stepName string) v1alpha1.WorkflowStepStatus { 29 return e.stepStatus 30 } 31 32 func (e *testEngine) GetCommonStepStatus(stepName string) v1alpha1.StepStatus { 33 return v1alpha1.StepStatus{} 34 } 35 36 func (e *testEngine) SetParentRunner(name string) { 37 } 38 39 func (e *testEngine) GetOperation() *types.Operation { 40 return e.operation 41 } 42 43 func TestStepGroupStep(t *testing.T) { 44 r := require.New(t) 45 ctx := newWorkflowContextForTest(t) 46 subRunner, err := StepGroup(v1alpha1.WorkflowStep{ 47 WorkflowStepBase: v1alpha1.WorkflowStepBase{ 48 Name: "sub", 49 }, 50 }, &types.TaskGeneratorOptions{ID: "1"}) 51 r.NoError(err) 52 runner, err := StepGroup(v1alpha1.WorkflowStep{ 53 WorkflowStepBase: v1alpha1.WorkflowStepBase{ 54 Name: "test", 55 DependsOn: []string{"depend"}, 56 }, 57 }, &types.TaskGeneratorOptions{ID: "124", SubTaskRunners: []types.TaskRunner{subRunner}, ProcessContext: process.NewContext(process.ContextData{})}) 58 r.NoError(err) 59 r.Equal(runner.Name(), "test") 60 61 // test pending 62 logCtx := monitorContext.NewTraceContext(context.Background(), "test-app") 63 p, _ := runner.Pending(logCtx, ctx, nil) 64 r.Equal(p, true) 65 ss := map[string]v1alpha1.StepStatus{ 66 "depend": { 67 Phase: v1alpha1.WorkflowStepPhaseSucceeded, 68 }, 69 } 70 p, _ = runner.Pending(logCtx, ctx, ss) 71 r.Equal(p, false) 72 73 // test skip 74 status, operations, err := runner.Run(ctx, &types.TaskRunOptions{ 75 PreCheckHooks: []types.TaskPreCheckHook{ 76 func(step v1alpha1.WorkflowStep, options *types.PreCheckOptions) (*types.PreCheckResult, error) { 77 return &types.PreCheckResult{Skip: true}, nil 78 }, 79 }, 80 StepStatus: map[string]v1alpha1.StepStatus{}, 81 Engine: &testEngine{ 82 stepStatus: v1alpha1.WorkflowStepStatus{}, 83 operation: &types.Operation{}, 84 }, 85 }) 86 r.NoError(err) 87 r.Equal(status.Phase, v1alpha1.WorkflowStepPhaseSkipped) 88 r.Equal(status.Reason, types.StatusReasonSkip) 89 r.Equal(operations.Skip, true) 90 91 // test timeout 92 status, operations, err = runner.Run(ctx, &types.TaskRunOptions{ 93 PreCheckHooks: []types.TaskPreCheckHook{ 94 func(step v1alpha1.WorkflowStep, options *types.PreCheckOptions) (*types.PreCheckResult, error) { 95 return &types.PreCheckResult{Timeout: true}, nil 96 }, 97 }, 98 StepStatus: map[string]v1alpha1.StepStatus{}, 99 Engine: &testEngine{ 100 stepStatus: v1alpha1.WorkflowStepStatus{}, 101 operation: &types.Operation{}, 102 }, 103 }) 104 r.NoError(err) 105 r.Equal(status.Phase, v1alpha1.WorkflowStepPhaseFailed) 106 r.Equal(status.Reason, types.StatusReasonTimeout) 107 r.Equal(operations.Terminated, true) 108 109 // test run 110 testCases := []struct { 111 name string 112 engine *testEngine 113 expectedPhase v1alpha1.WorkflowStepPhase 114 }{ 115 { 116 name: "running1", 117 engine: &testEngine{ 118 stepStatus: v1alpha1.WorkflowStepStatus{}, 119 operation: &types.Operation{}, 120 }, 121 expectedPhase: v1alpha1.WorkflowStepPhaseRunning, 122 }, 123 { 124 name: "running2", 125 engine: &testEngine{ 126 stepStatus: v1alpha1.WorkflowStepStatus{ 127 SubStepsStatus: []v1alpha1.StepStatus{ 128 { 129 Phase: v1alpha1.WorkflowStepPhaseRunning, 130 }, 131 }, 132 }, 133 operation: &types.Operation{}, 134 }, 135 expectedPhase: v1alpha1.WorkflowStepPhaseRunning, 136 }, 137 { 138 name: "fail", 139 engine: &testEngine{ 140 stepStatus: v1alpha1.WorkflowStepStatus{ 141 SubStepsStatus: []v1alpha1.StepStatus{ 142 { 143 Phase: v1alpha1.WorkflowStepPhaseFailed, 144 }, 145 { 146 Phase: v1alpha1.WorkflowStepPhaseSucceeded, 147 }, 148 }, 149 }, 150 operation: &types.Operation{}, 151 }, 152 expectedPhase: v1alpha1.WorkflowStepPhaseFailed, 153 }, 154 { 155 name: "success", 156 engine: &testEngine{ 157 stepStatus: v1alpha1.WorkflowStepStatus{ 158 SubStepsStatus: []v1alpha1.StepStatus{ 159 { 160 Phase: v1alpha1.WorkflowStepPhaseSucceeded, 161 }, 162 }, 163 }, 164 operation: &types.Operation{}, 165 }, 166 expectedPhase: v1alpha1.WorkflowStepPhaseSucceeded, 167 }, 168 { 169 name: "operation", 170 engine: &testEngine{ 171 stepStatus: v1alpha1.WorkflowStepStatus{ 172 SubStepsStatus: []v1alpha1.StepStatus{ 173 { 174 Phase: v1alpha1.WorkflowStepPhaseSucceeded, 175 }, 176 }, 177 }, 178 operation: &types.Operation{ 179 Suspend: true, 180 Terminated: true, 181 FailedAfterRetries: true, 182 Waiting: true, 183 }, 184 }, 185 expectedPhase: v1alpha1.WorkflowStepPhaseSucceeded, 186 }, 187 } 188 for _, tc := range testCases { 189 t.Run(tc.name, func(t *testing.T) { 190 status, act, err := runner.Run(ctx, &types.TaskRunOptions{ 191 Engine: tc.engine, 192 }) 193 r.NoError(err) 194 r.Equal(status.ID, "124") 195 r.Equal(status.Name, "test") 196 r.Equal(act.Suspend, tc.engine.operation.Suspend) 197 r.Equal(status.Phase, tc.expectedPhase) 198 }) 199 } 200 } 201 202 func newWorkflowContextForTest(t *testing.T) wfContext.Context { 203 cm := corev1.ConfigMap{} 204 r := require.New(t) 205 testCaseJson, err := yaml.YAMLToJSON([]byte(testCaseYaml)) 206 r.NoError(err) 207 err = json.Unmarshal(testCaseJson, &cm) 208 r.NoError(err) 209 210 wfCtx := new(wfContext.WorkflowContext) 211 err = wfCtx.LoadFromConfigMap(cm) 212 r.NoError(err) 213 return wfCtx 214 } 215 216 var ( 217 testCaseYaml = `apiVersion: v1 218 data: 219 test: "" 220 kind: ConfigMap 221 metadata: 222 name: app-v1 223 ` 224 )