github.com/SAP/cloud-mta-build-tool@v1.2.27/internal/buildops/build_params_test.go (about)

     1  package buildops
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/ginkgo/extensions/table"
    10  	. "github.com/onsi/gomega"
    11  
    12  	"github.com/SAP/cloud-mta-build-tool/internal/archive"
    13  	"github.com/SAP/cloud-mta-build-tool/internal/commands"
    14  	"github.com/SAP/cloud-mta/mta"
    15  )
    16  
    17  var _ = Describe("BuildParams", func() {
    18  
    19  	var _ = DescribeTable("valid cases", func(module *mta.Module, expected string) {
    20  		loc := &dir.Loc{SourcePath: getTestPath("mtahtml5")}
    21  		path, err := GetModuleSourceArtifactPath(loc, false, module, "", true)
    22  		Ω(err).Should(Succeed())
    23  		Ω(path).Should(Equal(expected))
    24  	},
    25  		Entry("Implicit Build Results Path", &mta.Module{Path: "testapp"}, getTestPath("mtahtml5", "testapp")),
    26  		Entry("Explicit Build Results Path",
    27  			&mta.Module{
    28  				Path:        "testapp",
    29  				BuildParams: map[string]interface{}{buildResultParam: filepath.Join("webapp", "controller")},
    30  			}, getTestPath("mtahtml5", "testapp", "webapp", "controller")))
    31  
    32  	var _ = Describe("GetBuildResultsPath", func() {
    33  		It("empty path, no build results", func() {
    34  			module := &mta.Module{}
    35  			buildResult, _ := GetModuleSourceArtifactPath(
    36  				&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "", true)
    37  			Ω(buildResult).Should(Equal(""))
    38  		})
    39  
    40  		It("build results - pattern", func() {
    41  			module := &mta.Module{
    42  				Path:        "inui2",
    43  				BuildParams: map[string]interface{}{buildResultParam: "*.txt"},
    44  			}
    45  			buildResult, _ := GetModuleSourceArtifactPath(
    46  				&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "", true)
    47  			Ω(buildResult).Should(HaveSuffix("anotherfile.txt"))
    48  		})
    49  
    50  		It("default build results", func() {
    51  			module := &mta.Module{
    52  				Path: "inui2",
    53  			}
    54  			buildResult, _ := GetModuleSourceArtifactPath(
    55  				&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "*.txt", true)
    56  			Ω(buildResult).Should(HaveSuffix("anotherfile.txt"))
    57  		})
    58  		It("default build results - no file answers pattern", func() {
    59  			module := &mta.Module{
    60  				Path: "inui2",
    61  			}
    62  			_, err := GetModuleSourceArtifactPath(
    63  				&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "b*.txt", true)
    64  			Ω(err).Should(HaveOccurred())
    65  		})
    66  	})
    67  
    68  	var _ = DescribeTable("getRequiredTargetPath", func(requires BuildRequires, module mta.Module, expected string) {
    69  		Ω(getRequiredTargetPath(&dir.Loc{}, &module, &requires)).Should(HaveSuffix(expected))
    70  	},
    71  		Entry("Implicit Target Path", BuildRequires{}, mta.Module{Path: "mPath"}, "mPath"),
    72  		Entry("Explicit Target Path", BuildRequires{TargetPath: "artifacts"}, mta.Module{Path: "mPath"}, filepath.Join("mPath", "artifacts")))
    73  
    74  	var _ = Describe("ProcessRequirements", func() {
    75  		wd, _ := os.Getwd()
    76  		ep := dir.Loc{SourcePath: filepath.Join(wd, "testdata", "testproject"), TargetPath: filepath.Join(wd, "testdata", "result")}
    77  		require := BuildRequires{
    78  			Name:       "A",
    79  			TargetPath: "./b_copied_artifacts",
    80  		}
    81  		require1 := BuildRequires{
    82  			Name:       "C",
    83  			TargetPath: "./b_copied_artifacts",
    84  		}
    85  		reqs := []BuildRequires{require}
    86  		reqs1 := []BuildRequires{require1}
    87  		mtaObj := mta.MTA{
    88  			Modules: []*mta.Module{
    89  				{
    90  					Name: "A",
    91  					Path: "ui5app",
    92  				},
    93  				{
    94  					Name: "B",
    95  					Path: "moduleB",
    96  					BuildParams: map[string]interface{}{
    97  						requiresParam: reqs,
    98  					},
    99  				},
   100  				{
   101  					Name: "C",
   102  					Path: "ui5app",
   103  					BuildParams: map[string]interface{}{
   104  						buildResultParam: "xxx.xxx",
   105  					},
   106  				},
   107  				{
   108  					Name: "D",
   109  					Path: "ui5app",
   110  					BuildParams: map[string]interface{}{
   111  						requiresParam: reqs1,
   112  					},
   113  				},
   114  			},
   115  		}
   116  
   117  		It("wrong builders configuration", func() {
   118  			conf := commands.BuilderTypeConfig
   119  			commands.BuilderTypeConfig = []byte("bad bad bad")
   120  			Ω(ProcessRequirements(&ep, &mtaObj, &require, "B")).Should(HaveOccurred())
   121  			commands.BuilderTypeConfig = conf
   122  		})
   123  
   124  		It("default build results - no file answers pattern", func() {
   125  			err := ProcessRequirements(&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")},
   126  				&mtaObj, &require1, "D")
   127  			Ω(err).Should(HaveOccurred())
   128  		})
   129  
   130  		AfterEach(func() {
   131  			os.RemoveAll(filepath.Join(wd, "testdata", "testproject", "moduleB"))
   132  		})
   133  
   134  		var _ = DescribeTable("Valid cases", func(artifacts []string, expectedPath string) {
   135  			require.Artifacts = artifacts
   136  			Ω(ProcessRequirements(&ep, &mtaObj, &require, "B")).Should(Succeed())
   137  			Ω(filepath.Join(wd, expectedPath)).Should(BeADirectory())
   138  			Ω(filepath.Join(wd, expectedPath, "webapp", "Component.js")).Should(BeAnExistingFile())
   139  		},
   140  			Entry("Require All - list", []string{"*"}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts")),
   141  			Entry("Require All - single value", []string{"*"}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts")),
   142  			Entry("Require All From Parent", []string{"."}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts", "ui5app")))
   143  
   144  		var _ = DescribeTable("Invalid cases", func(lp *dir.Loc, require BuildRequires, mtaObj mta.MTA, moduleName, buildResult string) {
   145  			Ω(ProcessRequirements(lp, &mtaObj, &require, moduleName)).Should(HaveOccurred())
   146  		},
   147  			Entry("Module not defined",
   148  				&dir.Loc{},
   149  				BuildRequires{Name: "A", Artifacts: []string{"*"}, TargetPath: "b_copied_artifacts"},
   150  				mta.MTA{Modules: []*mta.Module{{Name: "A", Path: "ui5app"}, {Name: "B", Path: "moduleB"}}},
   151  				"C", ""),
   152  			Entry("Required Module not defined",
   153  				&dir.Loc{},
   154  				BuildRequires{Name: "C", Artifacts: []string{"*"}, TargetPath: "b_copied_artifacts"},
   155  				mta.MTA{Modules: []*mta.Module{{Name: "A", Path: "ui5app"}, {Name: "B", Path: "moduleB"}}},
   156  				"B", ""),
   157  			Entry("Target path - file",
   158  				&dir.Loc{SourcePath: getTestPath("testbuildparams")},
   159  				BuildRequires{Name: "ui1", Artifacts: []string{"*"}, TargetPath: "file.txt"},
   160  				mta.MTA{Modules: []*mta.Module{{Name: "ui1", Path: "ui1"}, {Name: "node", Path: "node"}}},
   161  				"node", ""))
   162  
   163  	})
   164  })
   165  
   166  var _ = Describe("GetModuleTargetArtifactPath", func() {
   167  	It("path is empty", func() {
   168  		loc := dir.Loc{}
   169  		path, _, err := GetModuleTargetArtifactPath(&loc, false, &mta.Module{}, "", true)
   170  		Ω(err).Should(Succeed())
   171  		Ω(path).Should(BeEmpty())
   172  	})
   173  	It("fails when path doesn't exist", func() {
   174  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   175  		_, _, err := GetModuleTargetArtifactPath(&loc, false, &mta.Module{Path: "abc"}, "", true)
   176  		Ω(err).Should(HaveOccurred())
   177  	})
   178  	It("deployment descriptor", func() {
   179  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   180  		path, _, err := GetModuleTargetArtifactPath(&loc, true, &mta.Module{Path: "abc"}, "", true)
   181  		Ω(err).Should(Succeed())
   182  		Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "abc")))
   183  	})
   184  	It("fails on wrong definition of build result", func() {
   185  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   186  		module := &mta.Module{
   187  			Name: "web",
   188  			Path: "webapp",
   189  			BuildParams: map[string]interface{}{
   190  				buildResultParam: 1,
   191  			},
   192  		}
   193  		_, _, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   194  		Ω(err).Should(HaveOccurred())
   195  		Ω(err.Error()).Should(ContainSubstring(fmt.Sprintf(WrongBuildResultMsg, 1, "web")))
   196  	})
   197  	It("fails on wrong definition of build artifact name", func() {
   198  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   199  		module := &mta.Module{
   200  			Name: "web",
   201  			Path: filepath.Join("testapp", "webapp"),
   202  			BuildParams: map[string]interface{}{
   203  				buildArtifactNameParam: 1,
   204  			},
   205  		}
   206  		_, _, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   207  		Ω(err).Should(HaveOccurred())
   208  		Ω(err.Error()).Should(ContainSubstring(fmt.Sprintf(WrongBuildArtifactNameMsg, 1, "web")))
   209  	})
   210  	It("artifact is a folder", func() {
   211  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   212  		module := &mta.Module{
   213  			Name: "web",
   214  			Path: filepath.Join("testapp", "webapp"),
   215  			BuildParams: map[string]interface{}{
   216  				buildArtifactNameParam: "test",
   217  			},
   218  		}
   219  		path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   220  		Ω(err).Should(Succeed())
   221  		Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.zip")))
   222  		Ω(toArchive).Should(BeTrue())
   223  	})
   224  	It("artifact is a file", func() {
   225  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   226  		module := &mta.Module{
   227  			Name: "web",
   228  			Path: filepath.Join("testapp", "webapp", "Component.js"),
   229  			BuildParams: map[string]interface{}{
   230  				buildArtifactNameParam: "test",
   231  			},
   232  		}
   233  		path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   234  		Ω(err).Should(Succeed())
   235  		Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.zip")))
   236  		Ω(toArchive).Should(BeTrue())
   237  	})
   238  	It("artifact is a file defined by build result", func() {
   239  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   240  		module := &mta.Module{
   241  			Name: "web",
   242  			Path: "testapp",
   243  			BuildParams: map[string]interface{}{
   244  				buildResultParam:       filepath.Join("webapp", "controller", "View1.controller.js"),
   245  				buildArtifactNameParam: "ctrl",
   246  			},
   247  		}
   248  		path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   249  		Ω(err).Should(Succeed())
   250  		Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "webapp", "controller", "ctrl.zip")))
   251  		Ω(toArchive).Should(BeTrue())
   252  	})
   253  	It("artifact is an archive", func() {
   254  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   255  		module := &mta.Module{
   256  			Name: "web",
   257  			Path: filepath.Join("testapp", "webapp", "Component.jar"),
   258  			BuildParams: map[string]interface{}{
   259  				buildArtifactNameParam: "test",
   260  			},
   261  		}
   262  		path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true)
   263  		Ω(err).Should(Succeed())
   264  		Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.jar")))
   265  		Ω(toArchive).Should(BeFalse())
   266  	})
   267  	It("no build result resolving, path provided as pattern", func() {
   268  		loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")}
   269  		moduleLoc := dir.ModuleLocation(&loc, false)
   270  		module := &mta.Module{
   271  			Name: "web",
   272  			Path: filepath.Join("testapp", "webapp", "*.jar"),
   273  		}
   274  		path, toArchive, err := GetModuleTargetArtifactPath(moduleLoc, false, module, "", false)
   275  		Ω(err).Should(Succeed())
   276  		Ω(path).Should(Equal(getTestPath("result", "*.jar")))
   277  		Ω(toArchive).Should(BeFalse())
   278  	})
   279  })
   280  
   281  var _ = Describe("Process complex list of requirements", func() {
   282  	AfterEach(func() {
   283  		os.RemoveAll(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder"))
   284  		os.RemoveAll(getTestPath("testbuildparams", "node", "newfolder"))
   285  	})
   286  
   287  	It("", func() {
   288  		lp := dir.Loc{
   289  			SourcePath: getTestPath("testbuildparams"),
   290  			TargetPath: getTestPath("result"),
   291  		}
   292  		mtaObj, _ := lp.ParseFile()
   293  		for _, m := range mtaObj.Modules {
   294  			if m.Name == "node" {
   295  				for _, r := range GetBuildRequires(m) {
   296  					Ω(ProcessRequirements(&lp, mtaObj, &r, "node")).Should(Succeed())
   297  				}
   298  			}
   299  		}
   300  		// ["*"] => "newfolder"
   301  		Ω(getTestPath("testbuildparams", "node", "newfolder", "webapp")).Should(BeADirectory())
   302  		// ["deep/folder/inui2/anotherfile.txt"] => "existingfolder/deepfolder"
   303  		Ω(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder", "anotherfile.txt")).Should(BeAnExistingFile())
   304  		// ["./deep/*/inui2/another*"] => "./existingfolder/deepfolder"
   305  		Ω(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder", "anotherfile2.txt")).Should(BeAnExistingFile())
   306  		// ["deep/folder/inui2/somefile.txt", "*/folder/"] =>  "newfolder/newdeepfolder"
   307  		Ω(getTestPath("testbuildparams", "node", "newfolder", "newdeepfolder", "folder")).Should(BeADirectory())
   308  	})
   309  
   310  })
   311  
   312  var _ = Describe("PlatformDefined", func() {
   313  	It("No platforms", func() {
   314  		m := mta.Module{
   315  			Name: "x",
   316  			BuildParams: map[string]interface{}{
   317  				SupportedPlatformsParam: []string{},
   318  			},
   319  		}
   320  		Ω(PlatformDefined(&m, "cf")).Should(Equal(false))
   321  	})
   322  	It("All platforms", func() {
   323  		m := mta.Module{
   324  			Name:        "x",
   325  			BuildParams: map[string]interface{}{},
   326  		}
   327  		Ω(PlatformDefined(&m, "cf")).Should(Equal(true))
   328  	})
   329  	It("Matching platform", func() {
   330  		m := mta.Module{
   331  			Name: "x",
   332  			BuildParams: map[string]interface{}{
   333  				SupportedPlatformsParam: []string{"CF"},
   334  			},
   335  		}
   336  		Ω(PlatformDefined(&m, "cf")).Should(Equal(true))
   337  	})
   338  	It("Not Matching platform", func() {
   339  		m := mta.Module{
   340  			Name: "x",
   341  			BuildParams: map[string]interface{}{
   342  				SupportedPlatformsParam: []string{"neo"},
   343  			},
   344  		}
   345  		Ω(PlatformDefined(&m, "cf")).Should(Equal(false))
   346  	})
   347  	It("Matching platform - interface", func() {
   348  		m := mta.Module{
   349  			Name: "x",
   350  			BuildParams: map[string]interface{}{
   351  				SupportedPlatformsParam: []interface{}{"cf"},
   352  			},
   353  		}
   354  		Ω(PlatformDefined(&m, "cf")).Should(Equal(true))
   355  	})
   356  	It("Not Matching platform - interface", func() {
   357  		m := mta.Module{
   358  			Name: "x",
   359  			BuildParams: map[string]interface{}{
   360  				SupportedPlatformsParam: []interface{}{"neo"},
   361  			},
   362  		}
   363  		Ω(PlatformDefined(&m, "cf")).Should(Equal(false))
   364  	})
   365  })
   366  
   367  var _ = Describe("GetBuilder", func() {
   368  	It("Builder defined by type", func() {
   369  		m := mta.Module{
   370  			Name: "x",
   371  			Type: "node-js",
   372  			BuildParams: map[string]interface{}{
   373  				SupportedPlatformsParam: []string{},
   374  			},
   375  		}
   376  		builder, custom, _, cmds, err := commands.GetBuilder(&m)
   377  		Ω(builder).Should(Equal("node-js"))
   378  		Ω(custom).Should(BeFalse())
   379  		Ω(cmds).Should(BeNil())
   380  		Ω(err).Should(Succeed())
   381  	})
   382  	It("Builder defined by build params", func() {
   383  		m := mta.Module{
   384  			Name: "x",
   385  			Type: "node-js",
   386  			BuildParams: map[string]interface{}{
   387  				builderParam: "npm",
   388  				"npm-opts": map[string]interface{}{
   389  					"no-optional": nil,
   390  				},
   391  			},
   392  		}
   393  		builder, custom, _, cmds, err := commands.GetBuilder(&m)
   394  		Ω(builder).Should(Equal("npm"))
   395  		Ω(custom).Should(Equal(true))
   396  		Ω(len(cmds)).Should(Equal(0))
   397  		Ω(err).Should(Succeed())
   398  	})
   399  	It("Builder defined by build params", func() {
   400  		m := mta.Module{
   401  			Name: "x",
   402  			Type: "node-js",
   403  			BuildParams: map[string]interface{}{
   404  				builderParam: "custom",
   405  				"commands":   []string{"command1"},
   406  			},
   407  		}
   408  		builder, custom, _, cmds, err := commands.GetBuilder(&m)
   409  		Ω(builder).Should(Equal("custom"))
   410  		Ω(custom).Should(Equal(true))
   411  		Ω(cmds[0]).Should(Equal("command1"))
   412  		Ω(err).Should(Succeed())
   413  	})
   414  	It("fetcher builder defined by build params", func() {
   415  		m := mta.Module{
   416  			Name: "x",
   417  			Type: "node-js",
   418  			BuildParams: map[string]interface{}{
   419  				builderParam: "fetcher",
   420  				"fetcher-opts": map[interface{}]interface{}{
   421  					"repo-type":        "maven",
   422  					"repo-coordinates": "com.sap.xs.java:xs-audit-log-api:1.2.3",
   423  				},
   424  			},
   425  		}
   426  		builder, custom, options, cmds, err := commands.GetBuilder(&m)
   427  		Ω(options).Should(Equal(map[string]string{
   428  			"repo-type":        "maven",
   429  			"repo-coordinates": "com.sap.xs.java:xs-audit-log-api:1.2.3"}))
   430  		Ω(builder).Should(Equal("fetcher"))
   431  		Ω(custom).Should(BeTrue())
   432  		Ω(cmds).Should(BeNil())
   433  		Ω(err).Should(Succeed())
   434  	})
   435  	It("fetcher builder defined by build params from mta.yaml", func() {
   436  		currDir, err := os.Getwd()
   437  		Ω(err).Should(Succeed())
   438  		loc, err := dir.Location(filepath.Join(currDir, "testdata"), "", "dev", nil, os.Getwd)
   439  		Ω(err).Should(Succeed())
   440  		loc.MtaFilename = "mtaWithFetcher.yaml"
   441  		m, err := loc.ParseFile()
   442  		Ω(err).Should(Succeed())
   443  
   444  		builder, custom, options, cmds, err := commands.GetBuilder(m.Modules[0])
   445  		Ω(options).Should(Equal(map[string]string{
   446  			"repo-type":        "maven",
   447  			"repo-coordinates": "mygroup:myart:1.0.0"}))
   448  		Ω(builder).Should(Equal("fetcher"))
   449  		Ω(custom).Should(BeTrue())
   450  		Ω(cmds).Should(BeNil())
   451  		Ω(err).Should(Succeed())
   452  	})
   453  })
   454  
   455  var _ = Describe("IfNoSource", func() {
   456  	It("no source module", func() {
   457  		buildParams := make(map[string]interface{})
   458  		buildParams[noSourceParam] = true
   459  		module := mta.Module{BuildParams: buildParams}
   460  		Ω(IfNoSource(&module)).Should(BeTrue())
   461  	})
   462  	It("no source module", func() {
   463  		buildParams := make(map[string]interface{})
   464  		buildParams[noSourceParam] = false
   465  		module := mta.Module{BuildParams: buildParams}
   466  		Ω(IfNoSource(&module)).Should(BeFalse())
   467  	})
   468  	It("not no source module", func() {
   469  		buildParams := make(map[string]interface{})
   470  		module := mta.Module{BuildParams: buildParams}
   471  		Ω(IfNoSource(&module)).Should(BeFalse())
   472  	})
   473  })
   474  
   475  func getTestPath(relPath ...string) string {
   476  	wd, _ := os.Getwd()
   477  	return filepath.Join(wd, "testdata", filepath.Join(relPath...))
   478  }