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  )