github.com/kubeshop/testkube@v1.17.23/pkg/tcl/testworkflowstcl/testworkflowresolver/apply_test.go (about)

     1  // Copyright 2024 Testkube.
     2  //
     3  // Licensed as a Testkube Pro file under the Testkube Community
     4  // License (the "License"); you may not use this file except in compliance with
     5  // the License. You may obtain a copy of the License at
     6  //
     7  //     https://github.com/kubeshop/testkube/blob/main/licenses/TCL.txt
     8  
     9  package testworkflowresolver
    10  
    11  import (
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  	corev1 "k8s.io/api/core/v1"
    16  	"k8s.io/apimachinery/pkg/util/intstr"
    17  
    18  	testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1"
    19  )
    20  
    21  var (
    22  	tplPod = testworkflowsv1.TestWorkflowTemplate{
    23  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    24  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
    25  				Pod: &testworkflowsv1.PodConfig{
    26  					Labels: map[string]string{
    27  						"v1": "v2",
    28  					},
    29  				},
    30  			},
    31  		},
    32  	}
    33  	tplPodConfig = testworkflowsv1.TestWorkflowTemplate{
    34  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    35  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
    36  				Config: map[string]testworkflowsv1.ParameterSchema{
    37  					"department": {Type: testworkflowsv1.ParameterTypeString},
    38  				},
    39  				Pod: &testworkflowsv1.PodConfig{
    40  					Labels: map[string]string{
    41  						"department": "{{config.department}}",
    42  					},
    43  				},
    44  			},
    45  		},
    46  	}
    47  	tplEnv = testworkflowsv1.TestWorkflowTemplate{
    48  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    49  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
    50  				Container: &testworkflowsv1.ContainerConfig{
    51  					Env: []corev1.EnvVar{
    52  						{Name: "test", Value: "the"},
    53  					},
    54  				},
    55  			},
    56  		},
    57  	}
    58  	tplSteps = testworkflowsv1.TestWorkflowTemplate{
    59  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    60  			Setup: []testworkflowsv1.IndependentStep{
    61  				{StepBase: testworkflowsv1.StepBase{Name: "setup-tpl-test"}},
    62  			},
    63  			Steps: []testworkflowsv1.IndependentStep{
    64  				{StepBase: testworkflowsv1.StepBase{Name: "steps-tpl-test"}},
    65  			},
    66  			After: []testworkflowsv1.IndependentStep{
    67  				{StepBase: testworkflowsv1.StepBase{Name: "after-tpl-test"}},
    68  			},
    69  		},
    70  	}
    71  	tplStepsEnv = testworkflowsv1.TestWorkflowTemplate{
    72  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    73  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
    74  				Container: &testworkflowsv1.ContainerConfig{
    75  					Env: []corev1.EnvVar{
    76  						{Name: "test", Value: "the"},
    77  					},
    78  				},
    79  			},
    80  			Setup: []testworkflowsv1.IndependentStep{
    81  				{StepBase: testworkflowsv1.StepBase{Name: "setup-tpl-test"}},
    82  			},
    83  			Steps: []testworkflowsv1.IndependentStep{
    84  				{StepBase: testworkflowsv1.StepBase{Name: "steps-tpl-test"}},
    85  			},
    86  			After: []testworkflowsv1.IndependentStep{
    87  				{StepBase: testworkflowsv1.StepBase{Name: "after-tpl-test"}},
    88  			},
    89  		},
    90  	}
    91  	tplStepsConfig = testworkflowsv1.TestWorkflowTemplate{
    92  		Spec: testworkflowsv1.TestWorkflowTemplateSpec{
    93  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
    94  				Config: map[string]testworkflowsv1.ParameterSchema{
    95  					"index": {Type: testworkflowsv1.ParameterTypeInteger},
    96  				},
    97  			},
    98  			Setup: []testworkflowsv1.IndependentStep{
    99  				{StepBase: testworkflowsv1.StepBase{Name: "setup-tpl-test-{{ config.index }}"}},
   100  			},
   101  			Steps: []testworkflowsv1.IndependentStep{
   102  				{StepBase: testworkflowsv1.StepBase{Name: "steps-tpl-test-{{ config.index }}"}},
   103  			},
   104  			After: []testworkflowsv1.IndependentStep{
   105  				{StepBase: testworkflowsv1.StepBase{Name: "after-tpl-test-{{ config.index }}"}},
   106  			},
   107  		},
   108  	}
   109  	templates = map[string]testworkflowsv1.TestWorkflowTemplate{
   110  		"pod":         tplPod,
   111  		"podConfig":   tplPodConfig,
   112  		"env":         tplEnv,
   113  		"steps":       tplSteps,
   114  		"stepsEnv":    tplStepsEnv,
   115  		"stepsConfig": tplStepsConfig,
   116  	}
   117  	tplPodRef       = testworkflowsv1.TemplateRef{Name: "pod"}
   118  	tplPodConfigRef = testworkflowsv1.TemplateRef{
   119  		Name: "podConfig",
   120  		Config: map[string]intstr.IntOrString{
   121  			"department": {Type: intstr.String, StrVal: "test-department"},
   122  		},
   123  	}
   124  	tplPodConfigRefEmpty = testworkflowsv1.TemplateRef{Name: "podConfig"}
   125  	tplEnvRef            = testworkflowsv1.TemplateRef{Name: "env"}
   126  	tplStepsRef          = testworkflowsv1.TemplateRef{Name: "steps"}
   127  	tplStepsEnvRef       = testworkflowsv1.TemplateRef{Name: "stepsEnv"}
   128  	tplStepsConfigRef    = testworkflowsv1.TemplateRef{Name: "stepsConfig", Config: map[string]intstr.IntOrString{
   129  		"index": {Type: intstr.Int, IntVal: 20},
   130  	}}
   131  	tplStepsConfigRefStringInvalid = testworkflowsv1.TemplateRef{Name: "stepsConfig", Config: map[string]intstr.IntOrString{
   132  		"index": {Type: intstr.String, StrVal: "text"},
   133  	}}
   134  	tplStepsConfigRefStringValid = testworkflowsv1.TemplateRef{Name: "stepsConfig", Config: map[string]intstr.IntOrString{
   135  		"index": {Type: intstr.String, StrVal: "10"},
   136  	}}
   137  	workflowPod = testworkflowsv1.TestWorkflow{
   138  		Spec: testworkflowsv1.TestWorkflowSpec{
   139  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
   140  				Pod: &testworkflowsv1.PodConfig{
   141  					Labels: map[string]string{
   142  						"the": "value",
   143  					},
   144  				},
   145  			},
   146  		},
   147  	}
   148  	workflowPodConfig = testworkflowsv1.TestWorkflow{
   149  		Spec: testworkflowsv1.TestWorkflowSpec{
   150  			TestWorkflowSpecBase: testworkflowsv1.TestWorkflowSpecBase{
   151  				Config: map[string]testworkflowsv1.ParameterSchema{
   152  					"department": {Type: testworkflowsv1.ParameterTypeString},
   153  				},
   154  				Pod: &testworkflowsv1.PodConfig{
   155  					Labels: map[string]string{
   156  						"department": "{{config.department}}",
   157  					},
   158  				},
   159  			},
   160  		},
   161  	}
   162  	workflowSteps = testworkflowsv1.TestWorkflow{
   163  		Spec: testworkflowsv1.TestWorkflowSpec{
   164  			Setup: []testworkflowsv1.Step{
   165  				{StepBase: testworkflowsv1.StepBase{Name: "setup-tpl"}},
   166  			},
   167  			Steps: []testworkflowsv1.Step{
   168  				{StepBase: testworkflowsv1.StepBase{Name: "steps-tpl"}},
   169  			},
   170  			After: []testworkflowsv1.Step{
   171  				{StepBase: testworkflowsv1.StepBase{Name: "after-tpl"}},
   172  			},
   173  		},
   174  	}
   175  	basicStep = testworkflowsv1.Step{
   176  		StepBase: testworkflowsv1.StepBase{
   177  			Name:  "basic",
   178  			Shell: "shell-command",
   179  			Container: &testworkflowsv1.ContainerConfig{
   180  				Env: []corev1.EnvVar{
   181  					{Name: "XYZ", Value: "some-value"},
   182  				},
   183  			},
   184  		},
   185  	}
   186  	advancedStep = testworkflowsv1.Step{
   187  		StepBase: testworkflowsv1.StepBase{
   188  			Name:      "basic",
   189  			Condition: "always",
   190  			Delay:     "5s",
   191  			Shell:     "another-shell-command",
   192  			Container: &testworkflowsv1.ContainerConfig{
   193  				Env: []corev1.EnvVar{
   194  					{Name: "XYZ", Value: "some-value"},
   195  				},
   196  			},
   197  			Artifacts: &testworkflowsv1.StepArtifacts{
   198  				Paths: []string{"a", "b", "c"},
   199  			},
   200  		},
   201  		Steps: []testworkflowsv1.Step{
   202  			basicStep,
   203  		},
   204  	}
   205  )
   206  
   207  func TestApplyTemplatesMissingTemplate(t *testing.T) {
   208  	wf := workflowSteps.DeepCopy()
   209  	wf.Spec.Use = []testworkflowsv1.TemplateRef{{Name: "unknown"}}
   210  	err := ApplyTemplates(wf, templates)
   211  
   212  	assert.Error(t, err)
   213  	assert.Equal(t, err.Error(), `spec.use[0]: resolving template: template "unknown" not found`)
   214  }
   215  
   216  func TestApplyTemplatesMissingConfig(t *testing.T) {
   217  	wf := workflowSteps.DeepCopy()
   218  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplPodConfigRefEmpty}
   219  	err := ApplyTemplates(wf, templates)
   220  
   221  	assert.Error(t, err)
   222  	assert.Contains(t, err.Error(), `spec.use[0]: resolving template:`)
   223  	assert.Contains(t, err.Error(), `config.department: unknown variable`)
   224  }
   225  
   226  func TestApplyTemplatesInvalidConfig(t *testing.T) {
   227  	wf := workflowSteps.DeepCopy()
   228  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplStepsConfigRefStringInvalid}
   229  	err := ApplyTemplates(wf, templates)
   230  
   231  	assert.Error(t, err)
   232  	assert.Contains(t, err.Error(), `spec.use[0]: resolving template: config.index`)
   233  	assert.Contains(t, err.Error(), `error while converting value to number`)
   234  }
   235  
   236  func TestApplyTemplatesConfig(t *testing.T) {
   237  	wf := workflowPod.DeepCopy()
   238  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplPodConfigRef}
   239  	err := ApplyTemplates(wf, templates)
   240  
   241  	want := workflowPod.DeepCopy()
   242  	want.Spec.Pod.Labels["department"] = "test-department"
   243  
   244  	assert.NoError(t, err)
   245  	assert.Equal(t, want, wf)
   246  }
   247  
   248  func TestApplyTemplatesNoConfigMismatchNoOverride(t *testing.T) {
   249  	wf := workflowPodConfig.DeepCopy()
   250  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplPodConfigRef}
   251  	err := ApplyTemplates(wf, templates)
   252  
   253  	want := workflowPodConfig.DeepCopy()
   254  	want.Spec.Pod.Labels["department"] = "{{config.department}}"
   255  
   256  	assert.NoError(t, err)
   257  	assert.Equal(t, want, wf)
   258  }
   259  
   260  func TestApplyTemplatesMergeTopLevelSteps(t *testing.T) {
   261  	wf := workflowSteps.DeepCopy()
   262  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplStepsRef}
   263  	err := ApplyTemplates(wf, templates)
   264  
   265  	want := workflowSteps.DeepCopy()
   266  	want.Spec.Setup = []testworkflowsv1.Step{
   267  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   268  		want.Spec.Setup[0],
   269  	}
   270  	want.Spec.Steps = []testworkflowsv1.Step{
   271  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   272  		want.Spec.Steps[0],
   273  	}
   274  	want.Spec.After = []testworkflowsv1.Step{
   275  		want.Spec.After[0],
   276  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   277  	}
   278  
   279  	assert.NoError(t, err)
   280  	assert.Equal(t, want, wf)
   281  }
   282  
   283  func TestApplyTemplatesMergeMultipleTopLevelSteps(t *testing.T) {
   284  	wf := workflowSteps.DeepCopy()
   285  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplStepsRef, tplStepsConfigRef}
   286  	err := ApplyTemplates(wf, templates)
   287  
   288  	want := workflowSteps.DeepCopy()
   289  	want.Spec.Setup = []testworkflowsv1.Step{
   290  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Setup[0]),
   291  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   292  		want.Spec.Setup[0],
   293  	}
   294  	want.Spec.Setup[0].Name = "setup-tpl-test-20"
   295  	want.Spec.Steps = []testworkflowsv1.Step{
   296  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Steps[0]),
   297  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   298  		want.Spec.Steps[0],
   299  	}
   300  	want.Spec.Steps[0].Name = "steps-tpl-test-20"
   301  	want.Spec.After = []testworkflowsv1.Step{
   302  		want.Spec.After[0],
   303  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   304  		ConvertIndependentStepToStep(tplStepsConfig.Spec.After[0]),
   305  	}
   306  	want.Spec.After[2].Name = "after-tpl-test-20"
   307  
   308  	assert.NoError(t, err)
   309  	assert.Equal(t, want, wf)
   310  }
   311  
   312  func TestApplyTemplatesMergeMultipleConfigurable(t *testing.T) {
   313  	wf := workflowSteps.DeepCopy()
   314  	wf.Spec.Use = []testworkflowsv1.TemplateRef{tplStepsConfigRefStringValid, tplStepsConfigRef}
   315  	err := ApplyTemplates(wf, templates)
   316  
   317  	want := workflowSteps.DeepCopy()
   318  	want.Spec.Setup = []testworkflowsv1.Step{
   319  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Setup[0]),
   320  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Setup[0]),
   321  		want.Spec.Setup[0],
   322  	}
   323  	want.Spec.Setup[0].Name = "setup-tpl-test-20"
   324  	want.Spec.Setup[1].Name = "setup-tpl-test-10"
   325  	want.Spec.Steps = []testworkflowsv1.Step{
   326  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Steps[0]),
   327  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Steps[0]),
   328  		want.Spec.Steps[0],
   329  	}
   330  	want.Spec.Steps[0].Name = "steps-tpl-test-20"
   331  	want.Spec.Steps[1].Name = "steps-tpl-test-10"
   332  	want.Spec.After = []testworkflowsv1.Step{
   333  		want.Spec.After[0],
   334  		ConvertIndependentStepToStep(tplStepsConfig.Spec.After[0]),
   335  		ConvertIndependentStepToStep(tplStepsConfig.Spec.After[0]),
   336  	}
   337  	want.Spec.After[1].Name = "after-tpl-test-10"
   338  	want.Spec.After[2].Name = "after-tpl-test-20"
   339  
   340  	assert.NoError(t, err)
   341  	assert.Equal(t, want, wf)
   342  }
   343  
   344  func TestApplyTemplatesStepBasic(t *testing.T) {
   345  	s := *basicStep.DeepCopy()
   346  	s.Use = []testworkflowsv1.TemplateRef{tplEnvRef}
   347  	s, err := applyTemplatesToStep(s, templates)
   348  
   349  	want := *basicStep.DeepCopy()
   350  	want.Container.Env = append(tplEnv.Spec.Container.Env, want.Container.Env...)
   351  
   352  	assert.NoError(t, err)
   353  	assert.Equal(t, want, s)
   354  }
   355  
   356  func TestApplyTemplatesStepIgnorePod(t *testing.T) {
   357  	s := *basicStep.DeepCopy()
   358  	s.Use = []testworkflowsv1.TemplateRef{tplPodRef}
   359  	s, err := applyTemplatesToStep(s, templates)
   360  
   361  	want := *basicStep.DeepCopy()
   362  
   363  	assert.NoError(t, err)
   364  	assert.Equal(t, want, s)
   365  }
   366  
   367  func TestApplyTemplatesStepBasicIsolatedIgnore(t *testing.T) {
   368  	s := *basicStep.DeepCopy()
   369  	s.Template = &tplEnvRef
   370  	s, err := applyTemplatesToStep(s, templates)
   371  
   372  	want := *basicStep.DeepCopy()
   373  
   374  	assert.NoError(t, err)
   375  	assert.Equal(t, want, s)
   376  }
   377  
   378  func TestApplyTemplatesStepBasicIsolated(t *testing.T) {
   379  	s := *basicStep.DeepCopy()
   380  	s.Template = &tplStepsRef
   381  	s, err := applyTemplatesToStep(s, templates)
   382  
   383  	want := *basicStep.DeepCopy()
   384  	want.Steps = append([]testworkflowsv1.Step{
   385  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   386  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   387  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   388  	}, want.Steps...)
   389  
   390  	assert.NoError(t, err)
   391  	assert.Equal(t, want, s)
   392  }
   393  
   394  func TestApplyTemplatesStepBasicIsolatedWrapped(t *testing.T) {
   395  	s := *basicStep.DeepCopy()
   396  	s.Template = &tplStepsEnvRef
   397  	s, err := applyTemplatesToStep(s, templates)
   398  
   399  	want := *basicStep.DeepCopy()
   400  	want.Steps = append([]testworkflowsv1.Step{{
   401  		StepBase: testworkflowsv1.StepBase{
   402  			Container: tplStepsEnv.Spec.Container,
   403  		},
   404  		Setup: []testworkflowsv1.Step{
   405  			ConvertIndependentStepToStep(tplStepsEnv.Spec.Setup[0]),
   406  		},
   407  		Steps: []testworkflowsv1.Step{
   408  			ConvertIndependentStepToStep(tplStepsEnv.Spec.Steps[0]),
   409  			ConvertIndependentStepToStep(tplStepsEnv.Spec.After[0]),
   410  		},
   411  	}}, want.Steps...)
   412  
   413  	assert.NoError(t, err)
   414  	assert.Equal(t, want, s)
   415  }
   416  
   417  func TestApplyTemplatesStepBasicSteps(t *testing.T) {
   418  	s := *basicStep.DeepCopy()
   419  	s.Use = []testworkflowsv1.TemplateRef{tplStepsRef}
   420  	s, err := applyTemplatesToStep(s, templates)
   421  
   422  	want := *basicStep.DeepCopy()
   423  	want.Setup = []testworkflowsv1.Step{
   424  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   425  	}
   426  	want.Steps = append([]testworkflowsv1.Step{
   427  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   428  	}, append(want.Steps, []testworkflowsv1.Step{
   429  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   430  	}...)...)
   431  
   432  	assert.NoError(t, err)
   433  	assert.Equal(t, want, s)
   434  }
   435  
   436  func TestApplyTemplatesStepBasicMultipleSteps(t *testing.T) {
   437  	s := *basicStep.DeepCopy()
   438  	s.Use = []testworkflowsv1.TemplateRef{tplStepsRef, tplStepsConfigRef}
   439  	s, err := applyTemplatesToStep(s, templates)
   440  
   441  	want := *basicStep.DeepCopy()
   442  	want.Setup = []testworkflowsv1.Step{
   443  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Setup[0]),
   444  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   445  	}
   446  	want.Steps = append([]testworkflowsv1.Step{
   447  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Steps[0]),
   448  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   449  	}, append(want.Steps, []testworkflowsv1.Step{
   450  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   451  		ConvertIndependentStepToStep(tplStepsConfig.Spec.After[0]),
   452  	}...)...)
   453  	want.Setup[0].Name = "setup-tpl-test-20"
   454  	want.Steps[0].Name = "steps-tpl-test-20"
   455  	want.Steps[3].Name = "after-tpl-test-20"
   456  
   457  	assert.NoError(t, err)
   458  	assert.Equal(t, want, s)
   459  }
   460  
   461  func TestApplyTemplatesStepAdvancedIsolated(t *testing.T) {
   462  	s := *advancedStep.DeepCopy()
   463  	s.Template = &tplStepsRef
   464  	s, err := applyTemplatesToStep(s, templates)
   465  
   466  	want := *advancedStep.DeepCopy()
   467  	want.Steps = append([]testworkflowsv1.Step{
   468  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   469  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   470  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   471  	}, want.Steps...)
   472  
   473  	assert.NoError(t, err)
   474  	assert.Equal(t, want, s)
   475  }
   476  
   477  func TestApplyTemplatesStepAdvancedIsolatedWrapped(t *testing.T) {
   478  	s := *advancedStep.DeepCopy()
   479  	s.Template = &tplStepsEnvRef
   480  	s, err := applyTemplatesToStep(s, templates)
   481  
   482  	want := *advancedStep.DeepCopy()
   483  	want.Steps = append([]testworkflowsv1.Step{{
   484  		StepBase: testworkflowsv1.StepBase{
   485  			Container: tplStepsEnv.Spec.Container,
   486  		},
   487  		Setup: []testworkflowsv1.Step{
   488  			ConvertIndependentStepToStep(tplStepsEnv.Spec.Setup[0]),
   489  		},
   490  		Steps: []testworkflowsv1.Step{
   491  			ConvertIndependentStepToStep(tplStepsEnv.Spec.Steps[0]),
   492  			ConvertIndependentStepToStep(tplStepsEnv.Spec.After[0]),
   493  		},
   494  	}}, want.Steps...)
   495  
   496  	assert.NoError(t, err)
   497  	assert.Equal(t, want, s)
   498  }
   499  
   500  func TestApplyTemplatesStepAdvancedSteps(t *testing.T) {
   501  	s := *advancedStep.DeepCopy()
   502  	s.Use = []testworkflowsv1.TemplateRef{tplStepsRef}
   503  	s, err := applyTemplatesToStep(s, templates)
   504  
   505  	want := *advancedStep.DeepCopy()
   506  	want.Setup = []testworkflowsv1.Step{
   507  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   508  	}
   509  	want.Steps = append([]testworkflowsv1.Step{
   510  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   511  	}, append(want.Steps, []testworkflowsv1.Step{
   512  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   513  	}...)...)
   514  
   515  	assert.NoError(t, err)
   516  	assert.Equal(t, want, s)
   517  }
   518  
   519  func TestApplyTemplatesStepAdvancedMultipleSteps(t *testing.T) {
   520  	s := *advancedStep.DeepCopy()
   521  	s.Use = []testworkflowsv1.TemplateRef{tplStepsRef, tplStepsConfigRef}
   522  	s, err := applyTemplatesToStep(s, templates)
   523  
   524  	want := *advancedStep.DeepCopy()
   525  	want.Setup = []testworkflowsv1.Step{
   526  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Setup[0]),
   527  		ConvertIndependentStepToStep(tplSteps.Spec.Setup[0]),
   528  	}
   529  	want.Steps = append([]testworkflowsv1.Step{
   530  		ConvertIndependentStepToStep(tplStepsConfig.Spec.Steps[0]),
   531  		ConvertIndependentStepToStep(tplSteps.Spec.Steps[0]),
   532  	}, append(want.Steps, []testworkflowsv1.Step{
   533  		ConvertIndependentStepToStep(tplSteps.Spec.After[0]),
   534  		ConvertIndependentStepToStep(tplStepsConfig.Spec.After[0]),
   535  	}...)...)
   536  	want.Setup[0].Name = "setup-tpl-test-20"
   537  	want.Steps[0].Name = "steps-tpl-test-20"
   538  	want.Steps[4].Name = "after-tpl-test-20"
   539  
   540  	assert.NoError(t, err)
   541  	assert.Equal(t, want, s)
   542  }
   543  
   544  func TestApplyTemplatesConfigOverflow(t *testing.T) {
   545  	wf := workflowPod.DeepCopy()
   546  	wf.Spec.Use = []testworkflowsv1.TemplateRef{{
   547  		Name: "podConfig",
   548  		Config: map[string]intstr.IntOrString{
   549  			"department": {Type: intstr.String, StrVal: "{{config.value}}"},
   550  		},
   551  	}}
   552  	err := ApplyTemplates(wf, templates)
   553  
   554  	want := workflowPod.DeepCopy()
   555  	want.Spec.Pod.Labels["department"] = "{{config.value}}"
   556  
   557  	assert.NoError(t, err)
   558  	assert.Equal(t, want, wf)
   559  }