github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/abapEnvironmentBuild_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package cmd
     5  
     6  import (
     7  	"encoding/json"
     8  	"testing"
     9  	"time"
    10  
    11  	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
    12  	"github.com/SAP/jenkins-library/pkg/abaputils"
    13  	"github.com/SAP/jenkins-library/pkg/mock"
    14  	"github.com/SAP/jenkins-library/pkg/piperutils"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  type abapEnvironmentBuildMockUtils struct {
    19  	*mock.ExecMockRunner
    20  	*abapbuild.MockClient
    21  	*mock.FilesMock
    22  }
    23  
    24  func newAbapEnvironmentBuildTestsUtils() abapEnvironmentBuildUtils {
    25  	mC := abapbuild.GetBuildMockClientToRun2Times()
    26  	utils := abapEnvironmentBuildMockUtils{
    27  		ExecMockRunner: &mock.ExecMockRunner{},
    28  		MockClient:     &mC,
    29  		FilesMock:      &mock.FilesMock{},
    30  	}
    31  	return &utils
    32  }
    33  
    34  func newAbapEnvironmentBuildTestsUtilsWithClient() abapEnvironmentBuildUtils {
    35  	mC := abapbuild.GetBuildMockClientWithClient()
    36  	utils := abapEnvironmentBuildMockUtils{
    37  		ExecMockRunner: &mock.ExecMockRunner{},
    38  		MockClient:     &mC,
    39  		FilesMock:      &mock.FilesMock{},
    40  	}
    41  	return &utils
    42  }
    43  
    44  func (mB abapEnvironmentBuildMockUtils) PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) {
    45  }
    46  func (mB abapEnvironmentBuildMockUtils) GetAbapCommunicationArrangementInfo(options abaputils.AbapEnvironmentOptions, oDataURL string) (abaputils.ConnectionDetailsHTTP, error) {
    47  	var cd abaputils.ConnectionDetailsHTTP
    48  	cd.URL = "/sap/opu/odata/BUILD/CORE_SRV"
    49  	return cd, nil
    50  }
    51  
    52  func (mB abapEnvironmentBuildMockUtils) publish() {
    53  }
    54  
    55  func (mB abapEnvironmentBuildMockUtils) GetPollIntervall() time.Duration {
    56  	return 1 * time.Microsecond
    57  }
    58  
    59  func (mB abapEnvironmentBuildMockUtils) getMaxRuntime() time.Duration {
    60  	return 1 * time.Second
    61  }
    62  func (mB abapEnvironmentBuildMockUtils) getPollingInterval() time.Duration {
    63  	return 1 * time.Microsecond
    64  }
    65  
    66  func TestRunAbapEnvironmentBuild(t *testing.T) {
    67  	t.Parallel()
    68  	t.Run("happy path", func(t *testing.T) {
    69  		t.Parallel()
    70  		// init
    71  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
    72  		config := abapEnvironmentBuildOptions{}
    73  		config.AddonDescriptor = addonDescriptor
    74  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
    75  		config.DownloadAllResultFiles = true
    76  		config.PublishAllDownloadedResultFiles = true
    77  		utils := newAbapEnvironmentBuildTestsUtils()
    78  		// test
    79  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
    80  		// assert
    81  		finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"AunitValue1"},{"value_id":"MyId2","value":"AunitValue2"},{"value_id":"BUILD_FRAMEWORK_MODE","value":"P"}]`
    82  		assert.NoError(t, err)
    83  		assert.Equal(t, finalValues, cpe.abap.buildValues)
    84  	})
    85  
    86  	t.Run("happy path, use client", func(t *testing.T) {
    87  		t.Parallel()
    88  		// init
    89  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
    90  		config := abapEnvironmentBuildOptions{}
    91  		config.AddonDescriptor = addonDescriptor
    92  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
    93  		config.AbapSourceClient = "001"
    94  		utils := newAbapEnvironmentBuildTestsUtilsWithClient()
    95  		// test
    96  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
    97  		// assert
    98  		finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"SUN","value":"SUMMER"}]`
    99  		assert.NoError(t, err)
   100  		assert.Equal(t, finalValues, cpe.abap.buildValues)
   101  	})
   102  
   103  	t.Run("happy path, download only one", func(t *testing.T) {
   104  		t.Parallel()
   105  		// init
   106  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
   107  		config := abapEnvironmentBuildOptions{}
   108  		config.AddonDescriptor = addonDescriptor
   109  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   110  		config.DownloadResultFilenames = []string{"SAR_XML"}
   111  		config.PublishResultFilenames = []string{"SAR_XML"}
   112  		utils := newAbapEnvironmentBuildTestsUtils()
   113  		// test
   114  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
   115  		// assert
   116  		assert.NoError(t, err)
   117  	})
   118  
   119  	t.Run("happy path, use AddonDescriptor", func(t *testing.T) {
   120  		t.Parallel()
   121  		// init
   122  		expectedValueList := []abapbuild.Value{}
   123  		recordedValueList := []abapbuild.Value{}
   124  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
   125  		config := abapEnvironmentBuildOptions{}
   126  		config.AddonDescriptor = addonDescriptor
   127  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"}]`
   128  		//config.ConditionOnAddonDescriptor = `[{"field":"PackageType","operator":"!=","value":"AOI"}]`
   129  		//The mock client returns MyId1 & and MyId2 therefore we rename it to these values so that we can remove it from the output
   130  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"MyId1"},{"use":"Status","renameTo":"MyId2"}]`
   131  		utils := newAbapEnvironmentBuildTestsUtils()
   132  		// test
   133  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
   134  		// assert
   135  		finalValues := `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"}]`
   136  		err = json.Unmarshal([]byte(finalValues), &expectedValueList)
   137  		assert.NoError(t, err)
   138  		err = json.Unmarshal([]byte(cpe.abap.buildValues), &recordedValueList)
   139  		assert.NoError(t, err)
   140  		assert.NoError(t, err)
   141  		assert.ElementsMatch(t, expectedValueList, recordedValueList)
   142  	})
   143  
   144  	t.Run("error path, try to publish file, which was not downloaded", func(t *testing.T) {
   145  		t.Parallel()
   146  		// init
   147  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
   148  		config := abapEnvironmentBuildOptions{}
   149  		config.AddonDescriptor = addonDescriptor
   150  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   151  		config.DownloadResultFilenames = []string{"DELIVERY_LOGS.ZIP"}
   152  		config.PublishResultFilenames = []string{"SAR_XML"}
   153  		utils := newAbapEnvironmentBuildTestsUtils()
   154  		// test
   155  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
   156  		// assert
   157  		assert.Error(t, err)
   158  	})
   159  
   160  	t.Run("error path, try to download file which does not exist", func(t *testing.T) {
   161  		t.Parallel()
   162  		// init
   163  		cpe := abapEnvironmentBuildCommonPipelineEnvironment{}
   164  		config := abapEnvironmentBuildOptions{}
   165  		config.AddonDescriptor = addonDescriptor
   166  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   167  		config.DownloadResultFilenames = []string{"DOES_NOT_EXIST"}
   168  		config.PublishAllDownloadedResultFiles = true
   169  		utils := newAbapEnvironmentBuildTestsUtils()
   170  		// test
   171  		err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
   172  		// assert
   173  		assert.Error(t, err)
   174  	})
   175  }
   176  
   177  func TestGenerateValues(t *testing.T) {
   178  	t.Run("happy path", func(t *testing.T) {
   179  		// init
   180  		config := abapEnvironmentBuildOptions{}
   181  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   182  		config.CpeValues = `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"CPE_PACKAGE"},{"value_id":"MyId2","value":"Value2"}]`
   183  		// test
   184  		values, err := generateValuesOnlyFromConfig(&config)
   185  		// assert
   186  		assert.NoError(t, err)
   187  		assert.Equal(t, 3, len(values))
   188  
   189  		//values generated by map -> therefore we can not just iterate over the generated values and check them, as they are in random order
   190  		checkMap := map[string]string{
   191  			"PACKAGES": "/BUILD/AUNIT_DUMMY_TESTS",
   192  			"MyId1":    "Value1",
   193  			"MyId2":    "Value2",
   194  		}
   195  		for _, value := range values {
   196  			checkValue, present := checkMap[value.ValueID]
   197  			assert.True(t, present)
   198  			assert.Equal(t, checkValue, value.Value)
   199  		}
   200  	})
   201  	t.Run("happy path, use addonDescriptor", func(t *testing.T) {
   202  		// init
   203  		config := abapEnvironmentBuildOptions{}
   204  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   205  		config.CpeValues = `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"CPE_PACKAGE"},{"value_id": "Status","value":"R"},{"value_id":"MyId2","value":"Value2"}]`
   206  		config.AddonDescriptor = addonDescriptor
   207  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   208  		// test
   209  		valuesAddonDescriptor, err := evaluateAddonDescriptor(&config)
   210  		values0, err := generateValuesWithAddonDescriptor(&config, valuesAddonDescriptor[0])
   211  		// assert
   212  		assert.NoError(t, err)
   213  		assert.Equal(t, 5, len(values0))
   214  		//values generated by map -> therefore we can not just iterate over the generated values and check them, as they are in random order
   215  		checkMap := map[string]string{
   216  			"PACKAGES": "/BUILD/AUNIT_DUMMY_TESTS",
   217  			"MyId1":    "Value1",
   218  			"MyId2":    "Value2",
   219  			"SWC":      "/ITAPC1/I_CURRENCY",
   220  			"Status":   "P",
   221  		}
   222  		for _, value := range values0 {
   223  			checkValue, present := checkMap[value.ValueID]
   224  			assert.True(t, present)
   225  			assert.Equal(t, checkValue, value.Value)
   226  		}
   227  	})
   228  	t.Run("error path, use addonDescriptor already in config", func(t *testing.T) {
   229  		// init
   230  		config := abapEnvironmentBuildOptions{}
   231  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"},{"value_id":"Branch","value":"configBranch"}]`
   232  		config.CpeValues = `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"CPE_PACKAGE"},{"value_id": "Status","value":"R"},{"value_id":"MyId2","value":"Value2"}]`
   233  		config.AddonDescriptor = addonDescriptor
   234  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"},{"use":"Branch","renameTo":"Branch"}]`
   235  		// test
   236  		valuesAddonDescriptor, err := evaluateAddonDescriptor(&config)
   237  		values0, err := generateValuesWithAddonDescriptor(&config, valuesAddonDescriptor[0])
   238  		// assert
   239  		assert.Error(t, err)
   240  		assert.Equal(t, 0, len(values0))
   241  	})
   242  	t.Run("error path - duplicate in config", func(t *testing.T) {
   243  		// init
   244  		config := abapEnvironmentBuildOptions{}
   245  		config.Values = `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"},{"value_id":"MyId1","value":"Value1"}]`
   246  		// test
   247  		values, err := generateValuesOnlyFromConfig(&config)
   248  		// assert
   249  		assert.Error(t, err)
   250  		assert.Equal(t, 0, len(values))
   251  	})
   252  	t.Run("error path - bad formating in config.Values", func(t *testing.T) {
   253  		// init
   254  		config := abapEnvironmentBuildOptions{}
   255  		config.Values = `[{"task_id":"PACKAGES","task":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"Value1"}]`
   256  		// test
   257  		_, err := generateValuesOnlyFromConfig(&config)
   258  		// assert
   259  		assert.Error(t, err)
   260  	})
   261  }
   262  
   263  func TestEvaluateAddonDescriptor(t *testing.T) {
   264  	//global init
   265  	config := abapEnvironmentBuildOptions{}
   266  	config.AddonDescriptor = addonDescriptor
   267  	t.Run("Find one", func(t *testing.T) {
   268  		// init
   269  		config.ConditionOnAddonDescriptor = `[{"field":"Name","operator":"==","value":"/ITAPC1/I_CURRENCY"},{"field":"Status","operator":"!=","value":"R"}]`
   270  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   271  		// test
   272  		values, err := evaluateAddonDescriptor(&config)
   273  		// assert
   274  		assert.NoError(t, err)
   275  		assert.Equal(t, 1, len(values))
   276  		assert.Equal(t, 2, len(values[0]))
   277  	})
   278  	t.Run("Find both", func(t *testing.T) {
   279  		// init
   280  		config.ConditionOnAddonDescriptor = `[{"field":"PackageType","operator":"==","value":"AOI"}]`
   281  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   282  		// test
   283  		values, err := evaluateAddonDescriptor(&config)
   284  		// assert
   285  		assert.NoError(t, err)
   286  		assert.Equal(t, 2, len(values))
   287  		assert.Equal(t, 2, len(values[0]))
   288  		assert.Equal(t, 2, len(values[1]))
   289  	})
   290  	t.Run("Find none", func(t *testing.T) {
   291  		// init
   292  		config.ConditionOnAddonDescriptor = `[{"field":"PackageType","operator":"!=","value":"AOI"}]`
   293  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   294  		// test
   295  		values, err := evaluateAddonDescriptor(&config)
   296  		// assert
   297  		assert.NoError(t, err)
   298  		assert.Equal(t, 0, len(values))
   299  	})
   300  	t.Run("No condition", func(t *testing.T) {
   301  		// init
   302  		config.ConditionOnAddonDescriptor = ``
   303  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   304  		// test
   305  		values, err := evaluateAddonDescriptor(&config)
   306  		// assert
   307  		assert.NoError(t, err)
   308  		assert.Equal(t, 2, len(values))
   309  		assert.Equal(t, 2, len(values[0]))
   310  		assert.Equal(t, 2, len(values[1]))
   311  	})
   312  	t.Run("No UseFields", func(t *testing.T) {
   313  		// init
   314  		config.ConditionOnAddonDescriptor = ``
   315  		config.UseFieldsOfAddonDescriptor = ``
   316  		// test
   317  		values, err := evaluateAddonDescriptor(&config)
   318  		// assert
   319  		assert.NoError(t, err)
   320  		assert.Equal(t, 0, len(values))
   321  	})
   322  	t.Run("Wrong fieldname", func(t *testing.T) {
   323  		// init
   324  		config.ConditionOnAddonDescriptor = `[{"fieldxxx":"Name","operator":"==","value":"/ITAPC1/I_CURRENCY"}]`
   325  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   326  		// test
   327  		values, err := evaluateAddonDescriptor(&config)
   328  		// assert
   329  		assert.Error(t, err)
   330  		assert.Equal(t, 0, len(values))
   331  	})
   332  	t.Run("Wrong value fieldname", func(t *testing.T) {
   333  		// init
   334  		config.ConditionOnAddonDescriptor = `[{"field":"Name","operator":"==","valuexxxx":"/ITAPC1/I_CURRENCY"}]`
   335  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   336  		// test
   337  		values, err := evaluateAddonDescriptor(&config)
   338  		// assert
   339  		assert.Error(t, err)
   340  		assert.Equal(t, 0, len(values))
   341  	})
   342  	t.Run("Field which does not exist", func(t *testing.T) {
   343  		// init
   344  		config.ConditionOnAddonDescriptor = `[{"field":"DoesNotExist","operator":"==","valuexxxx":"/ITAPC1/I_CURRENCY"}]`
   345  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   346  		// test
   347  		values, err := evaluateAddonDescriptor(&config)
   348  		// assert
   349  		assert.Error(t, err)
   350  		assert.Equal(t, 0, len(values))
   351  	})
   352  	t.Run("Wrong operator", func(t *testing.T) {
   353  		// init
   354  		config.ConditionOnAddonDescriptor = `[{"field":"Name","operator":"()","value":"/ITAPC1/I_CURRENCY"}]`
   355  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   356  		// test
   357  		values, err := evaluateAddonDescriptor(&config)
   358  		// assert
   359  		assert.Error(t, err)
   360  		assert.Equal(t, 0, len(values))
   361  	})
   362  	t.Run("Test UseFieldsOfAddonDescriptor: Bad formatting use", func(t *testing.T) {
   363  		// init
   364  		config.ConditionOnAddonDescriptor = ``
   365  		config.UseFieldsOfAddonDescriptor = `[{"usexxx":"Name","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   366  		// test
   367  		values, err := evaluateAddonDescriptor(&config)
   368  		// assert
   369  		assert.Error(t, err)
   370  		assert.Equal(t, 0, len(values))
   371  	})
   372  	t.Run("Test UseFieldsOfAddonDescriptor: Bad formatting as", func(t *testing.T) {
   373  		// init
   374  		config.ConditionOnAddonDescriptor = ``
   375  		config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"SWC"},{"use":"Status","asxxx":"Status"}]`
   376  		// test
   377  		values, err := evaluateAddonDescriptor(&config)
   378  		// assert
   379  		assert.Error(t, err)
   380  		assert.Equal(t, 0, len(values))
   381  	})
   382  	t.Run("Test UseFieldsOfAddonDescriptor: use which does not exist", func(t *testing.T) {
   383  		// init
   384  		config.ConditionOnAddonDescriptor = ``
   385  		config.UseFieldsOfAddonDescriptor = `[{"use":"DoesNotExist","renameTo":"SWC"},{"use":"Status","renameTo":"Status"}]`
   386  		// test
   387  		values, err := evaluateAddonDescriptor(&config)
   388  		// assert
   389  		assert.Error(t, err)
   390  		assert.Equal(t, 0, len(values))
   391  	})
   392  }
   393  
   394  func TestValues2String(t *testing.T) {
   395  	t.Run("dito", func(t *testing.T) {
   396  		var myValues []abapbuild.Value
   397  		myValues = append(myValues, abapbuild.Value{ValueID: "Name", Value: "Hugo"})
   398  		myValues = append(myValues, abapbuild.Value{ValueID: "Age", Value: "43"})
   399  		myValues = append(myValues, abapbuild.Value{ValueID: "Hight", Value: "17cm"})
   400  		myString := values2string(myValues)
   401  		assert.Equal(t, "Name = Hugo; Age = 43; Hight = 17cm", myString)
   402  	})
   403  }
   404  
   405  var addonDescriptor = `{
   406  	"addonProduct":"/ITAPC1/I_CURRENCZPRODUCT",
   407  	"addonVersion":"1.0.0",
   408  	"addonVersionAAK":"0001",
   409  	"AddonSpsLevel":"0000",
   410  	"AddonPatchLevel":"0000",
   411  	"TargetVectorID":"",
   412  	"repositories":[
   413  	  {
   414  		"name":"/ITAPC1/I_CURRENCY",
   415  		"tag":"",
   416  		"branch":"v1.0.0",
   417  		"commitID":"1cb96a82",
   418  		"version":"1.0.0",
   419  		"versionAAK":"0001",
   420  		"PackageName":"SAPK-004AAINITAPC1",
   421  		"PackageType":"AOI",
   422  		"SpLevel":"0000",
   423  		"PatchLevel":"0000",
   424  		"PredecessorCommitID":"",
   425  		"Status":"P",
   426  		"Namespace":"/ITAPC1/",
   427  		"SarXMLFilePath":"",
   428  		"languages":null,
   429  		"InBuildScope":false
   430  		},
   431  	  {
   432  		"name":"/ITAPC1/I_FLIGHT",
   433  		"tag":"",
   434  		"branch":"v2.0.0",
   435  		"commitID":"5b87c03",
   436  		"version":"2.0.0",
   437  		"versionAAK":"0001",
   438  		"PackageName":"SAPK-005AAINITAPC2",
   439  		"PackageType":"AOI",
   440  		"SpLevel":"0000",
   441  		"PatchLevel":"0000",
   442  		"PredecessorCommitID":"",
   443  		"Status":"R",
   444  		"Namespace":"/ITAPC1/",
   445  		"SarXMLFilePath":"",
   446  		"languages":null,
   447  		"InBuildScope":false
   448  		}
   449  	  ]
   450  	}`