github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/config/stepmeta_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package config
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func TestReadPipelineStepData(t *testing.T) {
    18  	var s StepData
    19  
    20  	t.Run("Success case", func(t *testing.T) {
    21  		myMeta := strings.NewReader("metadata:\n  name: testIt\nspec:\n  inputs:\n    params:\n      - name: testParamName\n    secrets:\n      - name: testSecret")
    22  		err := s.ReadPipelineStepData(io.NopCloser(myMeta)) // NopCloser "no-ops" the closing interface since strings do not need to be closed
    23  
    24  		if err != nil {
    25  			t.Errorf("Got error although no error expected: %v", err)
    26  		}
    27  
    28  		t.Run("step name", func(t *testing.T) {
    29  			if s.Metadata.Name != "testIt" {
    30  				t.Errorf("Meta name - got: %v, expected: %v", s.Metadata.Name, "testIt")
    31  			}
    32  		})
    33  
    34  		t.Run("param name", func(t *testing.T) {
    35  			if s.Spec.Inputs.Parameters[0].Name != "testParamName" {
    36  				t.Errorf("Step name - got: %v, expected: %v", s.Spec.Inputs.Parameters[0].Name, "testParamName")
    37  			}
    38  		})
    39  
    40  		t.Run("secret name", func(t *testing.T) {
    41  			if s.Spec.Inputs.Secrets[0].Name != "testSecret" {
    42  				t.Errorf("Step name - got: %v, expected: %v", s.Spec.Inputs.Secrets[0].Name, "testSecret")
    43  			}
    44  		})
    45  	})
    46  
    47  	t.Run("Read failure", func(t *testing.T) {
    48  		var rc errReadCloser
    49  		err := s.ReadPipelineStepData(rc)
    50  		if err == nil {
    51  			t.Errorf("Got no error although error expected.")
    52  		}
    53  	})
    54  
    55  	t.Run("Unmarshalling failure", func(t *testing.T) {
    56  		myMeta := strings.NewReader("metadata:\n\tname: testIt")
    57  		err := s.ReadPipelineStepData(io.NopCloser(myMeta))
    58  		if err == nil {
    59  			t.Errorf("Got no error although error expected.")
    60  		}
    61  	})
    62  }
    63  
    64  func TestGetParameterFilters(t *testing.T) {
    65  	metadata1 := StepData{
    66  		Spec: StepSpec{
    67  			Inputs: StepInputs{
    68  				Parameters: []StepParameters{
    69  					{Name: "paramOne", Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS", "ENV"}},
    70  					{Name: "paramTwo", Scope: []string{"STEPS", "STAGES", "PARAMETERS", "ENV"}},
    71  					{Name: "paramThree", Scope: []string{"STAGES", "PARAMETERS", "ENV"}},
    72  					{Name: "paramFour", Scope: []string{"PARAMETERS", "ENV"}},
    73  					{Name: "paramFive", Scope: []string{"ENV"}},
    74  					{Name: "paramSix"},
    75  					{Name: "paramSeven", Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, Conditions: []Condition{{Params: []Param{{Name: "buildTool", Value: "mta"}}}}},
    76  				},
    77  			},
    78  		},
    79  	}
    80  
    81  	metadata2 := StepData{
    82  		Spec: StepSpec{
    83  			Inputs: StepInputs{
    84  				Parameters: []StepParameters{
    85  					{Name: "paramOne", Scope: []string{"GENERAL"}},
    86  					{Name: "paramTwo", Scope: []string{"STEPS"}},
    87  					{Name: "paramThree", Scope: []string{"STAGES"}},
    88  					{Name: "paramFour", Scope: []string{"PARAMETERS"}},
    89  					{Name: "paramFive", Scope: []string{"ENV"}},
    90  					{Name: "paramSix"},
    91  				},
    92  			},
    93  		},
    94  	}
    95  
    96  	metadata3 := StepData{
    97  		Spec: StepSpec{
    98  			Inputs: StepInputs{
    99  				Parameters: []StepParameters{},
   100  			},
   101  		},
   102  	}
   103  
   104  	testTable := []struct {
   105  		Metadata              StepData
   106  		ExpectedAll           []string
   107  		ExpectedGeneral       []string
   108  		ExpectedStages        []string
   109  		ExpectedSteps         []string
   110  		ExpectedParameters    []string
   111  		ExpectedEnv           []string
   112  		NotExpectedAll        []string
   113  		NotExpectedGeneral    []string
   114  		NotExpectedStages     []string
   115  		NotExpectedSteps      []string
   116  		NotExpectedParameters []string
   117  		NotExpectedEnv        []string
   118  	}{
   119  		{
   120  			Metadata:              metadata1,
   121  			ExpectedGeneral:       []string{"verbose", "paramOne", "paramSeven", "mta"},
   122  			ExpectedSteps:         []string{"verbose", "paramOne", "paramTwo", "paramSeven", "mta"},
   123  			ExpectedStages:        []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramSeven", "mta"},
   124  			ExpectedParameters:    []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramSeven", "mta"},
   125  			ExpectedEnv:           []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSeven", "mta"},
   126  			ExpectedAll:           []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSix", "paramSeven", "mta"},
   127  			NotExpectedGeneral:    []string{"paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"},
   128  			NotExpectedSteps:      []string{"paramThree", "paramFour", "paramFive", "paramSix"},
   129  			NotExpectedStages:     []string{"paramFour", "paramFive", "paramSix"},
   130  			NotExpectedParameters: []string{"paramFive", "paramSix"},
   131  			NotExpectedEnv:        []string{"verbose", "paramSix", "mta"},
   132  			NotExpectedAll:        []string{},
   133  		},
   134  		{
   135  			Metadata:              metadata2,
   136  			ExpectedGeneral:       []string{"verbose", "paramOne"},
   137  			ExpectedSteps:         []string{"verbose", "paramTwo"},
   138  			ExpectedStages:        []string{"verbose", "paramThree"},
   139  			ExpectedParameters:    []string{"verbose", "paramFour"},
   140  			ExpectedEnv:           []string{"paramFive"},
   141  			ExpectedAll:           []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"},
   142  			NotExpectedGeneral:    []string{"paramTwo", "paramThree", "paramFour", "paramFive", "paramSix"},
   143  			NotExpectedSteps:      []string{"paramOne", "paramThree", "paramFour", "paramFive", "paramSix"},
   144  			NotExpectedStages:     []string{"paramOne", "paramTwo", "paramFour", "paramFive", "paramSix"},
   145  			NotExpectedParameters: []string{"paramOne", "paramTwo", "paramThree", "paramFive", "paramSix"},
   146  			NotExpectedEnv:        []string{"verbose", "paramOne", "paramTwo", "paramThree", "paramFour", "paramSix"},
   147  			NotExpectedAll:        []string{},
   148  		},
   149  		{
   150  			Metadata:           metadata3,
   151  			ExpectedGeneral:    []string{"verbose"},
   152  			ExpectedStages:     []string{"verbose"},
   153  			ExpectedSteps:      []string{"verbose"},
   154  			ExpectedParameters: []string{"verbose"},
   155  			ExpectedEnv:        []string{},
   156  			ExpectedAll:        []string{"verbose"},
   157  		},
   158  	}
   159  
   160  	for key, row := range testTable {
   161  		t.Run(fmt.Sprintf("Metadata%v", key), func(t *testing.T) {
   162  			filters := row.Metadata.GetParameterFilters()
   163  			t.Run("General", func(t *testing.T) {
   164  				for _, val := range filters.General {
   165  					if !sliceContains(row.ExpectedGeneral, val) {
   166  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.General)
   167  					}
   168  					if sliceContains(row.NotExpectedGeneral, val) {
   169  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.General)
   170  					}
   171  				}
   172  			})
   173  			t.Run("Steps", func(t *testing.T) {
   174  				for _, val := range filters.Steps {
   175  					if !sliceContains(row.ExpectedSteps, val) {
   176  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.Steps)
   177  					}
   178  					if sliceContains(row.NotExpectedSteps, val) {
   179  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.Steps)
   180  					}
   181  				}
   182  			})
   183  			t.Run("Stages", func(t *testing.T) {
   184  				for _, val := range filters.Stages {
   185  					if !sliceContains(row.ExpectedStages, val) {
   186  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.Stages)
   187  					}
   188  					if sliceContains(row.NotExpectedStages, val) {
   189  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.Stages)
   190  					}
   191  				}
   192  			})
   193  			t.Run("Parameters", func(t *testing.T) {
   194  				for _, val := range filters.Parameters {
   195  					if !sliceContains(row.ExpectedParameters, val) {
   196  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.Parameters)
   197  					}
   198  					if sliceContains(row.NotExpectedParameters, val) {
   199  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.Parameters)
   200  					}
   201  				}
   202  			})
   203  			t.Run("Env", func(t *testing.T) {
   204  				for _, val := range filters.Env {
   205  					if !sliceContains(row.ExpectedEnv, val) {
   206  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.Env)
   207  					}
   208  					if sliceContains(row.NotExpectedEnv, val) {
   209  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.Env)
   210  					}
   211  				}
   212  			})
   213  			t.Run("All", func(t *testing.T) {
   214  				for _, val := range filters.All {
   215  					if !sliceContains(row.ExpectedAll, val) {
   216  						t.Errorf("Creation of parameter filter failed, expected: %v to be contained in  %v", val, filters.All)
   217  					}
   218  					if sliceContains(row.NotExpectedAll, val) {
   219  						t.Errorf("Creation of parameter filter failed, expected: %v NOT to be contained in  %v", val, filters.All)
   220  					}
   221  				}
   222  			})
   223  		})
   224  	}
   225  }
   226  
   227  func TestGetContextParameterFilters(t *testing.T) {
   228  	metadata1 := StepData{
   229  		Spec: StepSpec{
   230  			Inputs: StepInputs{
   231  				Secrets: []StepSecrets{
   232  					{Name: "testSecret1", Type: "jenkins"},
   233  					{Name: "testSecret2", Type: "jenkins"},
   234  				},
   235  				Resources: []StepResources{
   236  					{Name: "buildDescriptor", Type: "stash"},
   237  				},
   238  			},
   239  		},
   240  	}
   241  
   242  	metadata2 := StepData{
   243  		Spec: StepSpec{
   244  			Containers: []Container{
   245  				{Name: "testcontainer"},
   246  				{Conditions: []Condition{
   247  					{Params: []Param{
   248  						{Name: "scanType", Value: "pip"},
   249  					}},
   250  				}},
   251  			},
   252  		},
   253  	}
   254  
   255  	metadata3 := StepData{
   256  		Spec: StepSpec{
   257  			Sidecars: []Container{
   258  				{Name: "testsidecar"},
   259  			},
   260  		},
   261  	}
   262  
   263  	metadata4 := StepData{
   264  		Spec: StepSpec{
   265  			Inputs: StepInputs{
   266  				Parameters: []StepParameters{
   267  					{ResourceRef: []ResourceReference{{Type: "vaultSecret"}}},
   268  				},
   269  			},
   270  		},
   271  	}
   272  
   273  	metadata5 := StepData{
   274  		Spec: StepSpec{
   275  			Inputs: StepInputs{
   276  				Parameters: []StepParameters{
   277  					{ResourceRef: []ResourceReference{{Type: "vaultSecretFile"}}},
   278  				},
   279  			},
   280  		},
   281  	}
   282  
   283  	t.Run("Secrets and stashes", func(t *testing.T) {
   284  		filters := metadata1.GetContextParameterFilters()
   285  		params := defaultParams("testSecret1", "testSecret2", "stashContent")
   286  		assert.Equal(t, params, filters.General, "incorrect filter General")
   287  		assert.Equal(t, params, filters.All, "incorrect filter All")
   288  		assert.Equal(t, params, filters.Steps, "incorrect filter Steps")
   289  		assert.Equal(t, params, filters.Stages, "incorrect filter Stages")
   290  		assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters")
   291  		assert.Equal(t, params, filters.Env, "incorrect filter Env")
   292  	})
   293  
   294  	t.Run("Containers", func(t *testing.T) {
   295  		filters := metadata2.GetContextParameterFilters()
   296  		params := defaultParams("containerCommand", "containerShell", "dockerEnvVars", "dockerImage", "dockerName", "dockerOptions", "dockerPullImage", "dockerVolumeBind", "dockerWorkspace", "dockerRegistryUrl", "dockerRegistryCredentialsId", "pip", "scanType")
   297  
   298  		assert.Equal(t, params, filters.All, "incorrect filter All")
   299  		assert.Equal(t, params, filters.General, "incorrect filter General")
   300  		assert.Equal(t, params, filters.Steps, "incorrect filter Steps")
   301  		assert.Equal(t, params, filters.Stages, "incorrect filter Stages")
   302  		assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters")
   303  		assert.Equal(t, params, filters.Env, "incorrect filter Env")
   304  	})
   305  
   306  	t.Run("Sidecars", func(t *testing.T) {
   307  		filters := metadata3.GetContextParameterFilters()
   308  		params := defaultParams("containerName", "containerPortMappings", "dockerName", "sidecarEnvVars", "sidecarImage", "sidecarName", "sidecarOptions", "sidecarPullImage", "sidecarReadyCommand", "sidecarVolumeBind", "sidecarWorkspace")
   309  		assert.Equal(t, params, filters.All, "incorrect filter All")
   310  		assert.Equal(t, params, filters.General, "incorrect filter General")
   311  		assert.Equal(t, params, filters.Steps, "incorrect filter Steps")
   312  		assert.Equal(t, params, filters.Stages, "incorrect filter Stages")
   313  		assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters")
   314  		assert.Equal(t, params, filters.Env, "incorrect filter Env")
   315  	})
   316  
   317  	t.Run("Vault", func(t *testing.T) {
   318  		filters := metadata4.GetContextParameterFilters()
   319  		params := defaultParams()
   320  		assert.Equal(t, params, filters.All, "incorrect filter All")
   321  		assert.Equal(t, params, filters.General, "incorrect filter General")
   322  		assert.Equal(t, params, filters.Steps, "incorrect filter Steps")
   323  		assert.Equal(t, params, filters.Stages, "incorrect filter Stages")
   324  		assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters")
   325  		assert.Equal(t, params, filters.Env, "incorrect filter Env")
   326  	})
   327  
   328  	t.Run("Vault", func(t *testing.T) {
   329  		filters := metadata5.GetContextParameterFilters()
   330  		params := defaultParams()
   331  		assert.Equal(t, params, filters.All, "incorrect filter All")
   332  		assert.Equal(t, params, filters.General, "incorrect filter General")
   333  		assert.Equal(t, params, filters.Steps, "incorrect filter Steps")
   334  		assert.Equal(t, params, filters.Stages, "incorrect filter Stages")
   335  		assert.Equal(t, params, filters.Parameters, "incorrect filter Parameters")
   336  		assert.Equal(t, params, filters.Env, "incorrect filter Env")
   337  	})
   338  }
   339  
   340  func TestGetContextDefaults(t *testing.T) {
   341  
   342  	t.Run("Positive case", func(t *testing.T) {
   343  		metadata := StepData{
   344  			Spec: StepSpec{
   345  				Inputs: StepInputs{
   346  					Resources: []StepResources{
   347  						{
   348  							Name: "buildDescriptor",
   349  							Type: "stash",
   350  							Conditions: []Condition{
   351  								{Params: []Param{
   352  									{Name: "scanType", Value: "abc"},
   353  								}},
   354  							},
   355  						},
   356  						{
   357  							Name: "source",
   358  							Type: "stash",
   359  							Conditions: []Condition{
   360  								{Params: []Param{
   361  									{Name: "scanType", Value: "abc"},
   362  								}},
   363  							},
   364  						},
   365  						{
   366  							Name: "test",
   367  							Type: "nonce",
   368  						},
   369  						{
   370  							Name: "test2",
   371  							Type: "stash",
   372  							Conditions: []Condition{
   373  								{Params: []Param{
   374  									{Name: "scanType", Value: "def"},
   375  								}},
   376  							},
   377  						},
   378  						{
   379  							Name: "test3",
   380  							Type: "stash",
   381  						},
   382  					},
   383  				},
   384  				Containers: []Container{
   385  					{
   386  						Command: []string{"test/command"},
   387  						EnvVars: []EnvVar{
   388  							{Name: "env1", Value: "val1"},
   389  							{Name: "env2", Value: "val2"},
   390  						},
   391  						Name:            "testcontainer",
   392  						Image:           "testImage:tag",
   393  						ImagePullPolicy: "Always",
   394  						Shell:           "/bin/bash",
   395  						WorkingDir:      "/test/dir",
   396  						Options: []Option{
   397  							{Name: "opt1", Value: "optValue1"},
   398  							{Name: "opt2", Value: "optValue2"},
   399  						},
   400  						//VolumeMounts: []VolumeMount{
   401  						//	{MountPath: "mp1", Name: "mn1"},
   402  						//	{MountPath: "mp2", Name: "mn2"},
   403  						//},
   404  					},
   405  				},
   406  				Sidecars: []Container{
   407  					{
   408  						Command: []string{"/sidecar/command"},
   409  						EnvVars: []EnvVar{
   410  							{Name: "env3", Value: "val3"},
   411  							{Name: "env4", Value: "val4"},
   412  						},
   413  						Name:            "testsidecar",
   414  						Image:           "testSidecarImage:tag",
   415  						ImagePullPolicy: "Never",
   416  						ReadyCommand:    "/sidecar/command",
   417  						WorkingDir:      "/sidecar/dir",
   418  						Options: []Option{
   419  							{Name: "opt3", Value: "optValue3"},
   420  							{Name: "opt4", Value: "optValue4"},
   421  						},
   422  						//VolumeMounts: []VolumeMount{
   423  						//	{MountPath: "mp3", Name: "mn3"},
   424  						//	{MountPath: "mp4", Name: "mn4"},
   425  						//},
   426  					},
   427  				},
   428  			},
   429  		}
   430  
   431  		cd, err := metadata.GetContextDefaults("testStep")
   432  
   433  		t.Run("No error", func(t *testing.T) {
   434  			if err != nil {
   435  				t.Errorf("No error expected but got error '%v'", err)
   436  			}
   437  		})
   438  
   439  		var d PipelineDefaults
   440  		d.ReadPipelineDefaults([]io.ReadCloser{cd})
   441  
   442  		assert.Equal(t, []interface{}{"buildDescriptor", "source"}, d.Defaults[0].Steps["testStep"]["abc"].(map[string]interface{})["stashContent"], "stashContent default not available")
   443  		assert.Equal(t, []interface{}{"test2"}, d.Defaults[0].Steps["testStep"]["def"].(map[string]interface{})["stashContent"], "stashContent default not available")
   444  		assert.Equal(t, []interface{}{"test3"}, d.Defaults[0].Steps["testStep"]["stashContent"], "stashContent default not available")
   445  		assert.Equal(t, "test/command", d.Defaults[0].Steps["testStep"]["containerCommand"], "containerCommand default not available")
   446  		assert.Equal(t, "testcontainer", d.Defaults[0].Steps["testStep"]["containerName"], "containerName default not available")
   447  		assert.Equal(t, "/bin/bash", d.Defaults[0].Steps["testStep"]["containerShell"], "containerShell default not available")
   448  		assert.Equal(t, map[string]interface{}{"env1": "val1", "env2": "val2"}, d.Defaults[0].Steps["testStep"]["dockerEnvVars"], "dockerEnvVars default not available")
   449  		assert.Equal(t, "testImage:tag", d.Defaults[0].Steps["testStep"]["dockerImage"], "dockerImage default not available")
   450  		assert.Equal(t, "testcontainer", d.Defaults[0].Steps["testStep"]["dockerName"], "dockerName default not available")
   451  		assert.Equal(t, true, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available")
   452  		assert.Equal(t, "/test/dir", d.Defaults[0].Steps["testStep"]["dockerWorkspace"], "dockerWorkspace default not available")
   453  		assert.Equal(t, []interface{}{"opt1 optValue1", "opt2 optValue2"}, d.Defaults[0].Steps["testStep"]["dockerOptions"], "dockerOptions default not available")
   454  		//assert.Equal(t, []interface{}{"mn1:mp1", "mn2:mp2"}, d.Defaults[0].Steps["testStep"]["dockerVolumeBind"], "dockerVolumeBind default not available")
   455  
   456  		assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarCommand"], "sidecarCommand default not available")
   457  		assert.Equal(t, map[string]interface{}{"env3": "val3", "env4": "val4"}, d.Defaults[0].Steps["testStep"]["sidecarEnvVars"], "sidecarEnvVars default not available")
   458  		assert.Equal(t, "testSidecarImage:tag", d.Defaults[0].Steps["testStep"]["sidecarImage"], "sidecarImage default not available")
   459  		assert.Equal(t, "testsidecar", d.Defaults[0].Steps["testStep"]["sidecarName"], "sidecarName default not available")
   460  		assert.Equal(t, false, d.Defaults[0].Steps["testStep"]["sidecarPullImage"], "sidecarPullImage default not available")
   461  		assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarReadyCommand"], "sidecarReadyCommand default not available")
   462  		assert.Equal(t, "/sidecar/dir", d.Defaults[0].Steps["testStep"]["sidecarWorkspace"], "sidecarWorkspace default not available")
   463  		assert.Equal(t, []interface{}{"opt3 optValue3", "opt4 optValue4"}, d.Defaults[0].Steps["testStep"]["sidecarOptions"], "sidecarOptions default not available")
   464  		//assert.Equal(t, []interface{}{"mn3:mp3", "mn4:mp4"}, d.Defaults[0].Steps["testStep"]["sidecarVolumeBind"], "sidecarVolumeBind default not available")
   465  	})
   466  
   467  	t.Run("Container conditions", func(t *testing.T) {
   468  		metadata := StepData{
   469  			Spec: StepSpec{
   470  				Inputs: StepInputs{
   471  					Parameters: []StepParameters{
   472  						{Name: "testParameter", Default: "test"},
   473  						{Name: "testConditionParameter", Default: "testConditionMet"},
   474  					},
   475  				},
   476  				Containers: []Container{
   477  					{
   478  						Image: "testImage1:tag",
   479  						Conditions: []Condition{
   480  							{
   481  								ConditionRef: "strings-equal",
   482  								Params:       []Param{{Name: "testConditionParameter", Value: "testConditionNotMet"}},
   483  							},
   484  						},
   485  					},
   486  					{
   487  						Image: "testImage2:tag",
   488  						Conditions: []Condition{
   489  							{
   490  								ConditionRef: "strings-equal",
   491  								Params:       []Param{{Name: "testConditionParameter", Value: "testConditionMet"}},
   492  							},
   493  						},
   494  					},
   495  				},
   496  			},
   497  		}
   498  
   499  		cd, err := metadata.GetContextDefaults("testStep")
   500  
   501  		assert.NoError(t, err)
   502  
   503  		var d PipelineDefaults
   504  		d.ReadPipelineDefaults([]io.ReadCloser{cd})
   505  
   506  		assert.Equal(t, "testConditionMet", d.Defaults[0].Steps["testStep"]["testConditionParameter"])
   507  		assert.Nil(t, d.Defaults[0].Steps["testStep"]["dockerImage"])
   508  
   509  		metParameter := d.Defaults[0].Steps["testStep"]["testConditionMet"].(map[string]interface{})
   510  		assert.Equal(t, "testImage2:tag", metParameter["dockerImage"])
   511  
   512  		notMetParameter := d.Defaults[0].Steps["testStep"]["testConditionNotMet"].(map[string]interface{})
   513  		assert.Equal(t, "testImage1:tag", notMetParameter["dockerImage"])
   514  	})
   515  
   516  	t.Run("If ImagePullPolicy not defined pullImage parameter not set", func(t *testing.T) {
   517  		metadata := StepData{
   518  			Spec: StepSpec{
   519  				Containers: []Container{
   520  					{
   521  						Image: "testImage1:tag",
   522  					},
   523  				},
   524  				Sidecars: []Container{
   525  					{
   526  						Image: "testImage1:tag",
   527  					},
   528  				},
   529  			},
   530  		}
   531  
   532  		cd, err := metadata.GetContextDefaults("testStep")
   533  
   534  		assert.NoError(t, err)
   535  
   536  		var d PipelineDefaults
   537  		d.ReadPipelineDefaults([]io.ReadCloser{cd})
   538  
   539  		assert.Equal(t, nil, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available")
   540  		assert.Equal(t, nil, d.Defaults[0].Steps["testStep"]["sidecarPullImage"], "sidecarPullImage default not available")
   541  	})
   542  
   543  	t.Run("Empty docker parameter values", func(t *testing.T) {
   544  		metadata := StepData{
   545  			Spec: StepSpec{
   546  				Containers: []Container{
   547  					{
   548  						Image:   "testImage1:tag",
   549  						Options: []Option{{Name: "entrypoint", Value: ""}},
   550  					},
   551  				},
   552  			},
   553  		}
   554  
   555  		cd, err := metadata.GetContextDefaults("testStep")
   556  
   557  		assert.NoError(t, err)
   558  
   559  		var d PipelineDefaults
   560  		d.ReadPipelineDefaults([]io.ReadCloser{cd})
   561  
   562  		assert.Equal(t, []interface{}{"entrypoint="}, d.Defaults[0].Steps["testStep"]["dockerOptions"])
   563  	})
   564  
   565  	t.Run("Negative case", func(t *testing.T) {
   566  		metadataErr := []StepData{
   567  			{},
   568  			{
   569  				Spec: StepSpec{},
   570  			},
   571  			{
   572  				Spec: StepSpec{
   573  					Containers: []Container{},
   574  					Sidecars:   []Container{},
   575  				},
   576  			},
   577  		}
   578  
   579  		t.Run("No containers/sidecars", func(t *testing.T) {
   580  			cd, _ := metadataErr[0].GetContextDefaults("testStep")
   581  
   582  			var d PipelineDefaults
   583  			d.ReadPipelineDefaults([]io.ReadCloser{cd})
   584  
   585  			//no assert since we just want to make sure that no panic occurs
   586  		})
   587  
   588  		t.Run("No command", func(t *testing.T) {
   589  			cd, _ := metadataErr[1].GetContextDefaults("testStep")
   590  
   591  			var d PipelineDefaults
   592  			d.ReadPipelineDefaults([]io.ReadCloser{cd})
   593  
   594  			//no assert since we just want to make sure that no panic occurs
   595  		})
   596  	})
   597  }
   598  
   599  func TestGetResourceParameters(t *testing.T) {
   600  	tt := []struct {
   601  		in       StepData
   602  		expected map[string]interface{}
   603  	}{
   604  		{
   605  			in:       StepData{Spec: StepSpec{Inputs: StepInputs{}}},
   606  			expected: map[string]interface{}{},
   607  		},
   608  		{
   609  			in: StepData{
   610  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   611  					{Name: "param1"},
   612  					{Name: "param2"},
   613  				}}}},
   614  			expected: map[string]interface{}{},
   615  		},
   616  		{
   617  			in: StepData{
   618  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   619  					{Name: "param1", ResourceRef: []ResourceReference{}},
   620  					{Name: "param2", ResourceRef: []ResourceReference{}},
   621  				}}}},
   622  			expected: map[string]interface{}{},
   623  		},
   624  		{
   625  			in: StepData{
   626  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   627  					{Name: "param1", ResourceRef: []ResourceReference{{Name: "notAvailable", Param: "envparam1"}}},
   628  					{Name: "param2", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"},
   629  				}}}},
   630  			expected: map[string]interface{}{"param2": "val2"},
   631  		},
   632  		{
   633  			in: StepData{
   634  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   635  					{Name: "param2", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"},
   636  					{Name: "param3", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonList"}}, Type: "[]string"},
   637  				}}}},
   638  			expected: map[string]interface{}{"param2": "val2", "param3": []interface{}{"value1", "value2"}},
   639  		},
   640  		{
   641  			in: StepData{
   642  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   643  					{Name: "param4", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonKeyValue"}}, Type: "map[string]interface{}"},
   644  				}}}},
   645  			expected: map[string]interface{}{"param4": map[string]interface{}{"key": "value"}},
   646  		},
   647  		{
   648  			in: StepData{
   649  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   650  					{Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam1"}}, Type: "noString"},
   651  					{Name: "param4", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "jsonKeyValueString"}}, Type: "string"},
   652  				}}}},
   653  			expected: map[string]interface{}{"param4": "{\"key\":\"valueString\"}"},
   654  		},
   655  		{
   656  			in: StepData{
   657  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   658  					{Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam1"}, {Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"},
   659  				}}}},
   660  			expected: map[string]interface{}{"param1": "val1"},
   661  		},
   662  		{
   663  			in: StepData{
   664  				Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
   665  					{Name: "param1", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "sthwhichclearlydoesntexist"}, {Name: "commonPipelineEnvironment", Param: "envparam2"}}, Type: "string"},
   666  				}}}},
   667  			expected: map[string]interface{}{"param1": "val2"},
   668  		},
   669  	}
   670  
   671  	dir := t.TempDir()
   672  
   673  	cpeDir := filepath.Join(dir, "commonPipelineEnvironment")
   674  	err := os.MkdirAll(cpeDir, 0700)
   675  	if err != nil {
   676  		t.Fatal("Failed to create sub directory")
   677  	}
   678  
   679  	os.WriteFile(filepath.Join(cpeDir, "envparam1"), []byte("val1"), 0700)
   680  	os.WriteFile(filepath.Join(cpeDir, "envparam2"), []byte("val2"), 0700)
   681  	os.WriteFile(filepath.Join(cpeDir, "jsonList.json"), []byte("[\"value1\",\"value2\"]"), 0700)
   682  	os.WriteFile(filepath.Join(cpeDir, "jsonKeyValue.json"), []byte("{\"key\":\"value\"}"), 0700)
   683  	os.WriteFile(filepath.Join(cpeDir, "jsonKeyValueString"), []byte("{\"key\":\"valueString\"}"), 0700)
   684  
   685  	for run, test := range tt {
   686  		t.Run(fmt.Sprintf("Run %v", run), func(t *testing.T) {
   687  			got := test.in.GetResourceParameters(dir, "commonPipelineEnvironment")
   688  			assert.Equal(t, test.expected, got)
   689  		})
   690  	}
   691  }
   692  
   693  func TestAvoidEmptyFields(t *testing.T) {
   694  	t.Parallel()
   695  	t.Run("ignore empty string", func(t *testing.T) {
   696  		t.Parallel()
   697  		m := make(map[string]interface{})
   698  		putStringIfNotEmpty(m, "key", "")
   699  		assert.Len(t, m, 0)
   700  	})
   701  	t.Run("add non-empty string", func(t *testing.T) {
   702  		t.Parallel()
   703  		m := make(map[string]interface{})
   704  		putStringIfNotEmpty(m, "key", "value")
   705  		assert.Equal(t, "value", m["key"])
   706  	})
   707  	t.Run("ignore empty slice", func(t *testing.T) {
   708  		t.Parallel()
   709  		m := make(map[string]interface{})
   710  		putSliceIfNotEmpty(m, "key", []string{})
   711  		assert.Len(t, m, 0)
   712  	})
   713  	t.Run("add non-empty slice", func(t *testing.T) {
   714  		t.Parallel()
   715  		m := make(map[string]interface{})
   716  		putSliceIfNotEmpty(m, "key", []string{"value"})
   717  		assert.Equal(t, []string{"value"}, m["key"])
   718  	})
   719  	t.Run("ignore empty map", func(t *testing.T) {
   720  		t.Parallel()
   721  		m := make(map[string]interface{})
   722  		value := make(map[string]string)
   723  		putMapIfNotEmpty(m, "key", value)
   724  		assert.Len(t, m, 0)
   725  	})
   726  	t.Run("add non-empty map", func(t *testing.T) {
   727  		t.Parallel()
   728  		m := make(map[string]interface{})
   729  		value := make(map[string]string)
   730  		value["param"] = "value"
   731  		putMapIfNotEmpty(m, "key", value)
   732  		assert.Equal(t, value, m["key"])
   733  	})
   734  }
   735  
   736  func TestOptionsAsStringSlice(t *testing.T) {
   737  	tt := []struct {
   738  		options  []Option
   739  		expected []string
   740  	}{
   741  		{options: []Option{}, expected: []string{}},
   742  		{options: []Option{{Name: "name1", Value: "value1"}}, expected: []string{"name1 value1"}},
   743  		{options: []Option{{Name: "name1", Value: "value1"}, {Name: "name2", Value: "value2"}}, expected: []string{"name1 value1", "name2 value2"}},
   744  		{options: []Option{{Name: "empty", Value: ""}}, expected: []string{"empty="}},
   745  	}
   746  
   747  	for _, test := range tt {
   748  		assert.Equal(t, test.expected, OptionsAsStringSlice(test.options))
   749  	}
   750  }
   751  
   752  func defaultParams(params ...string) []string {
   753  	vaultParams := []string{
   754  		"vaultAppRoleTokenCredentialsId",
   755  		"vaultAppRoleSecretTokenCredentialsId",
   756  		"vaultTokenCredentialsId",
   757  	}
   758  
   759  	stepParams := make([]string, 0, len(params)+len(vaultParams))
   760  	stepParams = append(stepParams, params...)
   761  	stepParams = append(stepParams, vaultParams...)
   762  
   763  	return stepParams
   764  }
   765  
   766  func testMetadataResolver() map[string]StepData {
   767  	return map[string]StepData{
   768  		"githubCreateIssue": {
   769  			Metadata: StepMetadata{
   770  				Name: "githubCreateIssue",
   771  			},
   772  		},
   773  	}
   774  }
   775  
   776  func TestResolveMetadata(t *testing.T) {
   777  
   778  	t.Run("Succes - stepName", func(t *testing.T) {
   779  		stepName := "githubCreateIssue"
   780  		stepData, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName)
   781  		assert.NoError(t, err)
   782  		assert.Equal(t, "githubCreateIssue", stepData.Metadata.Name)
   783  	})
   784  
   785  	t.Run("Error - wrong stepName", func(t *testing.T) {
   786  		stepName := "notExisting"
   787  		_, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName)
   788  		assert.EqualError(t, err, "could not retrieve by stepName notExisting")
   789  	})
   790  
   791  	t.Run("Error - missing input", func(t *testing.T) {
   792  		stepName := ""
   793  		_, err := ResolveMetadata(map[string]string{}, testMetadataResolver, "", stepName)
   794  		assert.EqualError(t, err, "either one of stepMetadata or stepName parameter has to be passed")
   795  	})
   796  }