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

     1  package artifacts
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  	"text/template"
     7  
     8  	. "github.com/onsi/ginkgo"
     9  	. "github.com/onsi/ginkgo/extensions/table"
    10  	. "github.com/onsi/gomega"
    11  	"github.com/pkg/errors"
    12  
    13  	"github.com/SAP/cloud-mta-build-tool/internal/archive"
    14  	"github.com/SAP/cloud-mta-build-tool/internal/buildops"
    15  	"github.com/SAP/cloud-mta-build-tool/internal/commands"
    16  	"github.com/SAP/cloud-mta-build-tool/internal/conttype"
    17  	"github.com/SAP/cloud-mta-build-tool/internal/version"
    18  	"github.com/SAP/cloud-mta/mta"
    19  )
    20  
    21  var _ = Describe("manifest", func() {
    22  
    23  	BeforeEach(func() {
    24  		createDirInTmpFolder("mta", "META-INF")
    25  	})
    26  
    27  	AfterEach(func() {
    28  		Ω(os.RemoveAll(getTestPath("result"))).Should(Succeed())
    29  	})
    30  
    31  	var _ = Describe("setManifestDesc", func() {
    32  		It("Sanity", func() {
    33  			createDirInTmpFolder("mta", "node-js")
    34  			createFileInTmpFolder("mta", "node-js", "data.zip")
    35  			createFileInTmpFolder("mta", "config-site-host.json")
    36  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath()}
    37  			mtaObj, err := loc.ParseFile()
    38  			Ω(err).Should(Succeed())
    39  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
    40  			actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
    41  			golden := getFileContent(getTestPath("golden_manifest.mf"))
    42  			v, _ := version.GetVersion()
    43  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
    44  			Ω(actual).Should(Equal(golden))
    45  		})
    46  		It("Unknown content type, assembly scenario", func() {
    47  			createDirInTmpFolder("mta", "node-js")
    48  			createFileInTmpFolder("mta", "node-js", "server.js")
    49  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), Descriptor: dir.Dep}
    50  			mtaObj, err := loc.ParseFile()
    51  			Ω(err).Should(Succeed())
    52  			err = setManifestDesc(&loc, &loc, &loc, true, mtaObj.Modules, []*mta.Resource{}, "cf")
    53  			checkError(err, conttype.ContentTypeUndefinedMsg, ".js")
    54  		})
    55  		It("Sanity - with configuration provided", func() {
    56  			// no_source module (with no-source build parameter) is not referenced in the manifest
    57  			createDirInTmpFolder("mta", "node-js")
    58  			createFileInTmpFolder("mta", "node-js", "data.zip")
    59  			createFileInTmpFolder("mta", "config-site-host.json")
    60  			createFileInTmpFolder("mta", "config-site-host1.json")
    61  			createFileInTmpFolder("mta", "xs-security.json")
    62  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mta_cfg.yaml"}
    63  			mtaObj, err := loc.ParseFile()
    64  			Ω(err).Should(Succeed())
    65  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
    66  			actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
    67  			golden := getFileContent(getTestPath("golden_manifest_cfg.mf"))
    68  			v, _ := version.GetVersion()
    69  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
    70  			Ω(actual).Should(Equal(golden))
    71  		})
    72  		It("wrong Commands configuration", func() {
    73  			createDirInTmpFolder("mta", "node-js")
    74  			createFileInTmpFolder("mta", "node-js", "data.zip")
    75  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath()}
    76  			mtaObj, err := loc.ParseFile()
    77  			Ω(err).Should(Succeed())
    78  			moduleConf := commands.ModuleTypeConfig
    79  			commands.ModuleTypeConfig = []byte("bad module conf")
    80  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(HaveOccurred())
    81  			commands.ModuleTypeConfig = moduleConf
    82  		})
    83  		It("module with defined build-result fails when build-result file does not exist in source directory", func() {
    84  			createDirInTmpFolder("mta", "node-js")
    85  			createFileInTmpFolder("mta", "node-js", "some.war")
    86  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaWrongBuildResult.yaml"}
    87  			mtaObj, err := loc.ParseFile()
    88  			Ω(err).Should(Succeed())
    89  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(HaveOccurred())
    90  		})
    91  		It("module with defined build-result fails when build-result file does not exist in target temp directory", func() {
    92  			createDirInTmpFolder("mta", "node-js")
    93  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaWrongBuildResult2.yaml"}
    94  			mtaObj, err := loc.ParseFile()
    95  			Ω(err).Should(Succeed())
    96  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(HaveOccurred())
    97  		})
    98  		It("entry for module with defined build-result has the build-result file", func() {
    99  			createDirInTmpFolder("mta", "node-js")
   100  			createFileInTmpFolder("mta", "node-js", "data1.zip")
   101  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildResult.yaml"}
   102  			mtaObj, err := loc.ParseFile()
   103  			Ω(err).Should(Succeed())
   104  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   105  			actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   106  			golden := getFileContent(getTestPath("golden_manifestBuildResult.mf"))
   107  			v, _ := version.GetVersion()
   108  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
   109  			Ω(actual).Should(Equal(golden))
   110  		})
   111  		It("wrong content types configuration", func() {
   112  			createDirInTmpFolder("mta", "node-js")
   113  			createFileInTmpFolder("mta", "node-js", "data.zip")
   114  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath()}
   115  			mtaObj, err := loc.ParseFile()
   116  			Ω(err).Should(Succeed())
   117  			contentTypesOrig := conttype.ContentTypeConfig
   118  			conttype.ContentTypeConfig = []byte(`wrong configuraion`)
   119  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(HaveOccurred())
   120  			conttype.ContentTypeConfig = contentTypesOrig
   121  
   122  		})
   123  		It("Sanity - module with no path is not added to the manifest", func() {
   124  			createDirInTmpFolder("mta", "node-js")
   125  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mta_no_paths.yaml"}
   126  			mtaObj, err := loc.ParseFile()
   127  			Ω(err).Should(Succeed())
   128  			Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   129  			actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   130  			golden := getFileContent(getTestPath("golden_assembly_manifest_no_paths.mf"))
   131  			v, _ := version.GetVersion()
   132  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
   133  			Ω(actual).Should(Equal(golden))
   134  		})
   135  		It("With resources", func() {
   136  			createDirInTmpFolder("assembly-sample", "META-INF")
   137  			createDirInTmpFolder("assembly-sample", "web")
   138  			createFileInTmpFolder("assembly-sample", "config-site-host.json")
   139  			createFileInTmpFolder("assembly-sample", "xs-security.json")
   140  			createDirInTmpFolder("assembly-sample", "inner")
   141  			createFileInTmpFolder("assembly-sample", "inner", "uaa.json")
   142  			createFileInTmpFolder("assembly-sample", "inner", "xs-security.json")
   143  			loc := dir.Loc{SourcePath: getTestPath("assembly-sample"), TargetPath: getResultPath(), Descriptor: "dep"}
   144  			mtaObj, err := loc.ParseFile()
   145  			Ω(err).Should(Succeed())
   146  			Ω(setManifestDesc(&loc, &loc, &loc, true, mtaObj.Modules, mtaObj.Resources, "cf")).Should(Succeed())
   147  			actual := getFileContent(getFullPathInTmpFolder("assembly-sample", "META-INF", "MANIFEST.MF"))
   148  			golden := getFileContent(getTestPath("golden_assembly_manifest.mf"))
   149  			v, _ := version.GetVersion()
   150  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
   151  			Ω(actual).Should(Equal(golden))
   152  		})
   153  		It("With missing module path", func() {
   154  			createDirInTmpFolder("assembly-sample", "META-INF")
   155  			loc := dir.Loc{SourcePath: getTestPath("assembly-sample"), TargetPath: getResultPath(), Descriptor: "dep"}
   156  			mtaObj, err := loc.ParseFile()
   157  			Ω(err).Should(Succeed())
   158  			err = setManifestDesc(&loc, &loc, &loc, true, mtaObj.Modules, mtaObj.Resources, "cf")
   159  			checkError(err, wrongArtifactPathMsg, "java-hello-world")
   160  		})
   161  		It("With missing resource", func() {
   162  			createDirInTmpFolder("assembly-sample", "META-INF")
   163  			createDirInTmpFolder("assembly-sample", "web")
   164  			createFileInTmpFolder("assembly-sample", "config-site-host.json")
   165  			createDirInTmpFolder("assembly-sample", "inner")
   166  			createFileInTmpFolder("assembly-sample", "inner", "uaa.json")
   167  			createFileInTmpFolder("assembly-sample", "inner", "xs-security.json")
   168  			loc := dir.Loc{SourcePath: getTestPath("assembly-sample"), TargetPath: getTestPath("result"), Descriptor: "dep"}
   169  			mtaObj, err := loc.ParseFile()
   170  			Ω(err).Should(Succeed())
   171  			err = setManifestDesc(&loc, &loc, &loc, true, mtaObj.Modules, mtaObj.Resources, "cf")
   172  			checkError(err, unknownResourceContentTypeMsg, "java-uaa")
   173  
   174  		})
   175  		It("required resource with path fails when the path doesn't exist", func() {
   176  			createDirInTmpFolder("assembly-sample", "META-INF")
   177  			createDirInTmpFolder("assembly-sample", "web")
   178  			createFileInTmpFolder("assembly-sample", "xs-security.json")
   179  			loc := dir.Loc{SourcePath: getTestPath("assembly-sample"), TargetPath: getTestPath("result"), Descriptor: "dep"}
   180  			mtaObj, err := loc.ParseFile()
   181  			Ω(err).Should(Succeed())
   182  			err = setManifestDesc(&loc, &loc, &loc, true, mtaObj.Modules, mtaObj.Resources, "cf")
   183  			// This fails because the config-site-host.json file (from the path of the required java-site-host) doesn't exist
   184  			checkError(err, requiredEntriesProblemMsg, "java-hello-world-backend")
   185  		})
   186  		When("build-artifact-name is defined in the build parameters", func() {
   187  			It("should take the defined build artifact name when the build artifact exists", func() {
   188  				createDirInTmpFolder("mta", "node-js")
   189  				createFileInTmpFolder("mta", "node-js", "data2.zip")
   190  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifact.yaml"}
   191  				mtaObj, err := loc.ParseFile()
   192  				Ω(err).Should(Succeed())
   193  				Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   194  				actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   195  				golden := getFileContentWithCliVersion(getTestPath("golden_manifestBuildArtifact.mf"))
   196  				Ω(actual).Should(Equal(golden))
   197  			})
   198  			It("should take the archive.zip with the build artifact name when the build result is a folder", func() {
   199  				createDirInTmpFolder("mta", "node-js")
   200  				createFileInTmpFolder("mta", "node-js", "data2.zip")
   201  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifact.yaml"}
   202  				mtaObj, err := loc.ParseFile()
   203  				Ω(err).Should(Succeed())
   204  				Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   205  				actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   206  				golden := getFileContentWithCliVersion(getTestPath("golden_manifestBuildArtifact.mf"))
   207  				Ω(actual).Should(Equal(golden))
   208  			})
   209  			It("should skip the module when it has no path", func() {
   210  				createDirInTmpFolder("mta", "node-js", "data2")
   211  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifactNoPath.yaml"}
   212  				mtaObj, err := loc.ParseFile()
   213  				Ω(err).Should(Succeed())
   214  				Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   215  				actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   216  				golden := getFileContentWithCliVersion(getTestPath("golden_assembly_manifest_no_paths.mf"))
   217  				Ω(actual).Should(Equal(golden))
   218  			})
   219  			It("should take the build artifact name when the build result is also defined", func() {
   220  				createDirInTmpFolder("mta", "node-js")
   221  				createFileInTmpFolder("mta", "node-js", "ROOT.war")
   222  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildResultAndArtifact.yaml"}
   223  				mtaObj, err := loc.ParseFile()
   224  				Ω(err).Should(Succeed())
   225  				Ω(setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")).Should(Succeed())
   226  				actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   227  				golden := getFileContentWithCliVersion(getTestPath("golden_manifestBuildResultAndArtifact.mf"))
   228  				Ω(actual).Should(Equal(golden))
   229  			})
   230  			It("should fail when build-artifact-name is not a string value", func() {
   231  				createDirInTmpFolder("mta", "node-js")
   232  				createFileInTmpFolder("mta", "node-js", "data.zip")
   233  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifactBad.yaml"}
   234  				mtaObj, err := loc.ParseFile()
   235  				Ω(err).Should(Succeed())
   236  				err = setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")
   237  				checkError(err, buildops.WrongBuildArtifactNameMsg, "1", "node-js")
   238  			})
   239  			It("should fail when data.zip exists instead of the build artifact name", func() {
   240  				createDirInTmpFolder("mta", "node-js")
   241  				createFileInTmpFolder("mta", "node-js", "data.zip")
   242  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifact.yaml"}
   243  				mtaObj, err := loc.ParseFile()
   244  				Ω(err).Should(Succeed())
   245  				err = setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")
   246  				checkError(err, wrongArtifactPathMsg, "node-js")
   247  			})
   248  			It("should fail when the build artifact doesn't exist in the module folder", func() {
   249  				createDirInTmpFolder("mta", "node-js")
   250  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifact.yaml"}
   251  				mtaObj, err := loc.ParseFile()
   252  				Ω(err).Should(Succeed())
   253  				err = setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")
   254  				checkError(err, wrongArtifactPathMsg, "node-js")
   255  			})
   256  			It("should fail when the module folder doesn't exist", func() {
   257  				loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath(), MtaFilename: "mtaBuildArtifact.yaml"}
   258  				mtaObj, err := loc.ParseFile()
   259  				Ω(err).Should(Succeed())
   260  				err = setManifestDesc(&loc, &loc, &loc, false, mtaObj.Modules, []*mta.Resource{}, "cf")
   261  				checkError(err, wrongArtifactPathMsg, "node-js")
   262  			})
   263  		})
   264  	})
   265  
   266  	var _ = Describe("genManifest", func() {
   267  		It("Sanity", func() {
   268  			loc := dir.Loc{SourcePath: getTestPath("mta"), TargetPath: getResultPath()}
   269  			entries := []entry{
   270  				{
   271  					EntryName:   "node-js",
   272  					EntryPath:   "node-js/data.zip",
   273  					EntryType:   moduleEntry,
   274  					ContentType: "application/zip",
   275  				},
   276  			}
   277  			Ω(genManifest(loc.GetManifestPath(), entries)).Should(Succeed())
   278  			actual := getFileContent(getFullPathInTmpFolder("mta", "META-INF", "MANIFEST.MF"))
   279  			golden := getFileContent(getTestPath("golden_manifest.mf"))
   280  			v, _ := version.GetVersion()
   281  			golden = strings.Replace(golden, "{{cli_version}}", v.CliVersion, -1)
   282  			Ω(actual).Should(Equal(golden))
   283  		})
   284  		It("Fails on wrong location", func() {
   285  			loc := dir.Loc{}
   286  			Ω(genManifest(loc.GetManifestPath(), []entry{})).Should(HaveOccurred())
   287  		})
   288  		It("Fails on wrong version configuration", func() {
   289  			versionCfg := version.VersionConfig
   290  			version.VersionConfig = []byte(`
   291  bad config
   292  `)
   293  			loc := dir.Loc{}
   294  			Ω(genManifest(loc.GetManifestPath(), []entry{})).Should(HaveOccurred())
   295  			version.VersionConfig = versionCfg
   296  		})
   297  	})
   298  	var _ = Describe("moduleDefined", func() {
   299  		It("not defined", func() {
   300  			Ω(moduleDefined("x", []string{"a"})).Should(BeFalse())
   301  		})
   302  		It("empty list", func() {
   303  			Ω(moduleDefined("x", []string{})).Should(BeTrue())
   304  		})
   305  		It("defined", func() {
   306  			Ω(moduleDefined("x", []string{"y", "x"})).Should(BeTrue())
   307  		})
   308  
   309  	})
   310  
   311  	var _ = Describe("populateManifest", func() {
   312  		It("Nil file failure", func() {
   313  
   314  			Ω(populateManifest(&testWriter{}, template.FuncMap{})).Should(HaveOccurred())
   315  		})
   316  	})
   317  
   318  	var _ = Describe("buildEntries", func() {
   319  		It("Sanity", func() {
   320  			createDirInTmpFolder("result", "node-js")
   321  			mod := mta.Module{Name: "module1"}
   322  			requires := []mta.Requires{
   323  				{
   324  					Name: "req",
   325  					Parameters: map[string]interface{}{
   326  						"path": "node-js",
   327  					},
   328  				},
   329  			}
   330  			entries, err := buildEntries(&dir.Loc{SourcePath: getTestPath("result"), TargetPath: getTestPath("result")}, &mod, requires, &conttype.ContentTypes{})
   331  			Ω(len(entries)).Should(Equal(1))
   332  			Ω(err).Should(Succeed())
   333  			e := entries[0]
   334  			Ω(e.EntryType).Should(Equal(requiredEntry))
   335  			Ω(e.EntryName).Should(Equal("module1/req"))
   336  			Ω(e.EntryPath).Should(Equal("node-js"))
   337  			Ω(e.ContentType).Should(Equal(dirContentType))
   338  		})
   339  
   340  	})
   341  
   342  	DescribeTable("mergeDuplicateEntries", func(entries []entry, expected []entry) {
   343  		actual := mergeDuplicateEntries(entries)
   344  		Ω(actual).Should(Equal(expected))
   345  	},
   346  		Entry("returns non-module entries unchanged", []entry{
   347  			{EntryName: "e1", EntryPath: "a", EntryType: resourceEntry, ContentType: "t"},
   348  			{EntryName: "e2", EntryPath: "a", EntryType: requiredEntry, ContentType: "t"},
   349  			{EntryName: "e3", EntryPath: "b", EntryType: resourceEntry, ContentType: "t"},
   350  			{EntryName: "e4", EntryPath: "b", EntryType: resourceEntry, ContentType: "t"},
   351  		}, []entry{
   352  			{EntryName: "e1", EntryPath: "a", EntryType: resourceEntry, ContentType: "t"},
   353  			{EntryName: "e2", EntryPath: "a", EntryType: requiredEntry, ContentType: "t"},
   354  			{EntryName: "e3", EntryPath: "b", EntryType: resourceEntry, ContentType: "t"},
   355  			{EntryName: "e4", EntryPath: "b", EntryType: resourceEntry, ContentType: "t"},
   356  		},
   357  		),
   358  		Entry("merges module entries with the same path and keeps the modules order", []entry{
   359  			{EntryName: "e1", EntryPath: "a", EntryType: moduleEntry, ContentType: "t1"},
   360  			{EntryName: "e2", EntryPath: "a", EntryType: moduleEntry, ContentType: "t2"},
   361  			{EntryName: "e3", EntryPath: "a", EntryType: moduleEntry, ContentType: "t3"},
   362  			{EntryName: "e4", EntryPath: "b", EntryType: moduleEntry, ContentType: "t4"},
   363  			{EntryName: "e5", EntryPath: "b", EntryType: moduleEntry, ContentType: "t5"},
   364  			{EntryName: "e6", EntryPath: "c", EntryType: moduleEntry, ContentType: "t6"},
   365  		}, []entry{
   366  			{EntryName: "e1, e2, e3", EntryPath: "a", EntryType: moduleEntry, ContentType: "t1"},
   367  			{EntryName: "e4, e5", EntryPath: "b", EntryType: moduleEntry, ContentType: "t4"},
   368  			{EntryName: "e6", EntryPath: "c", EntryType: moduleEntry, ContentType: "t6"},
   369  		},
   370  		),
   371  		Entry("merges module entries and keeps non-module entries unchanged at the end", []entry{
   372  			{EntryName: "e1", EntryPath: "a", EntryType: resourceEntry, ContentType: "t1"},
   373  			{EntryName: "e2", EntryPath: "a", EntryType: moduleEntry, ContentType: "t2"},
   374  			{EntryName: "e3", EntryPath: "a", EntryType: moduleEntry, ContentType: "t3"},
   375  			{EntryName: "e4", EntryPath: "b", EntryType: moduleEntry, ContentType: "t4"},
   376  			{EntryName: "e5", EntryPath: "b", EntryType: requiredEntry, ContentType: "t5"},
   377  		}, []entry{
   378  			{EntryName: "e2, e3", EntryPath: "a", EntryType: moduleEntry, ContentType: "t2"},
   379  			{EntryName: "e4", EntryPath: "b", EntryType: moduleEntry, ContentType: "t4"},
   380  			{EntryName: "e1", EntryPath: "a", EntryType: resourceEntry, ContentType: "t1"},
   381  			{EntryName: "e5", EntryPath: "b", EntryType: requiredEntry, ContentType: "t5"},
   382  		},
   383  		),
   384  	)
   385  
   386  	var _ = Describe("getContentType", func() {
   387  		It("fails on empty path", func() {
   388  			_, err := getContentType("", &conttype.ContentTypes{})
   389  			Ω(err).Should(HaveOccurred())
   390  		})
   391  	})
   392  })
   393  
   394  type testWriter struct {
   395  }
   396  
   397  func (t *testWriter) Write(p []byte) (n int, err error) {
   398  	return 0, errors.New("err")
   399  }
   400  
   401  func getFileContentWithCliVersion(path string) string {
   402  	content := getFileContent(path)
   403  	v, _ := version.GetVersion()
   404  	content = strings.Replace(content, "{{cli_version}}", v.CliVersion, -1)
   405  	return content
   406  }