diff --git a/go.mod b/go.mod index 3bb4b439..bad82569 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/devfile/library go 1.13 require ( - github.com/devfile/api/v2 v2.0.0-20210713153530-f78ab9de1a30 + github.com/devfile/api/v2 v2.0.0-20210804191700-4f7b6856e70a github.com/fatih/color v1.7.0 github.com/gobwas/glob v0.2.3 github.com/golang/mock v1.5.0 diff --git a/go.sum b/go.sum index 89ff6d80..76f1afe1 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devfile/api/v2 v2.0.0-20210713153530-f78ab9de1a30 h1:DL1o2U9NuS2KpVHva5h3tbIReJfF1LkSTJFj+JRiqJg= -github.com/devfile/api/v2 v2.0.0-20210713153530-f78ab9de1a30/go.mod h1:QNzaIVQnCsYfXed+QZOn1uvEQFzyhvpi/uc3g/b2ws0= +github.com/devfile/api/v2 v2.0.0-20210804191700-4f7b6856e70a h1:mvnXqJAjmdrsUltkE3sOh29UcI+0jKQ8kKKXYkWArNc= +github.com/devfile/api/v2 v2.0.0-20210804191700-4f7b6856e70a/go.mod h1:QNzaIVQnCsYfXed+QZOn1uvEQFzyhvpi/uc3g/b2ws0= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= diff --git a/tests/v2/devfiles/samples/Parent.yaml b/tests/v2/devfiles/samples/Parent.yaml new file mode 100644 index 00000000..5f315af7 --- /dev/null +++ b/tests/v2/devfiles/samples/Parent.yaml @@ -0,0 +1,82 @@ +schemaVersion: 2.1.0 +commands: +- apply: + component: testcontainerparent1 + group: + kind: test + isDefault: true + label: JXTVtfYNNsaiQcqFSwTavCaBlRGMaBOXaxXsgDRxFxsNxbuHfGQuQjBwJWJVmHd + id: testapplyparentcommand1 +- id: run + exec: + component: testcontainerparent1 + commandLine: npm start + workingDir: /project + group: + kind: run + isDefault: true + hotReloadCapable: true +- id: test + composite: + commands: [testapplyparentcommand1] + group: + kind: debug + label: testcompositeparent1 + parallel: true +components: + - container: + image: mKrpiOQnyGZ00003 + name: testcontainerparent1 + - kubernetes: + inlined: | + apiVersion: batch/v1 + kind: Job + metadata: + name: pi + spec: + template: + spec: + containers: + - name: job + image: myimage + command: ["some", "command"] + restartPolicy: Never + name: testkubeparent1 + - openshift: + uri: openshift.yaml + name: openshiftcomponent1 +projects: + - name: petclinic + git: + remotes: + origin: "https://github.com/spring-projects/spring-petclinic.git" + checkoutFrom: + remote: origin + revision: main + - name: petclinic-dev + zip: + location: https://github.com/spring-projects/spring-petclinic/archive/refs/heads/main.zip + attributes: + editorFree: true + user: default +starterProjects: + - name: user-app + git: + remotes: + origin: 'https://github.com/OpenLiberty/application-stack-starters.git' + description: An Open Liberty Starter project + subDir: /app + attributes: + workingDir: /home + - name: user-app2 + zip: + location: 'https://github.com/OpenLiberty/application-stack-starters.zip' +attributes: #only applicable to v2.1.0 + category: parentdevfile + title: This is a parent devfile +variables: #only applicable to v2.1.0 + version: 2.0.0 + tag: parent + lastUpdated: "2020" + + \ No newline at end of file diff --git a/tests/v2/devfiles/samples/Test_Parent_KubeCRD.yaml b/tests/v2/devfiles/samples/Test_Parent_KubeCRD.yaml new file mode 100644 index 00000000..4e13eba9 --- /dev/null +++ b/tests/v2/devfiles/samples/Test_Parent_KubeCRD.yaml @@ -0,0 +1,46 @@ +schemaVersion: 2.1.0 +parent: + kubernetes: + name: testkubeparent1 + namespace: default + commands: + - apply: + component: devbuild + group: + kind: build #override + isDefault: false #override + label: testcontainerparent1 #override + id: applycommand + components: + - container: + image: updatedimage #override + name: devbuild + projects: + - name: parentproject + git: + remotes: + neworigin: "https://github.com/spring-projects/spring-petclinic2.git" #override, should result in 2 remotes in flattened file + checkoutFrom: + remote: neworigin #override + revision: main #override + - name: parentproject2 + zip: + location: "https://github.com/spring-projects/spring-petclinic2.zip" #override + starterProjects: + - name: parentstarterproject + git: + remotes: + origin: "https://github.com/spring-projects/spring-petclinic2.git" #override + checkoutFrom: + remote: origin + revision: master #override + attributes: # only applicable to v2.1.0 + category: mainDevfile #override + title: This is a main devfile #override + variables: #only applicable to v2.1.0 + version: 2.1.0 #override + tag: main #override + + + + diff --git a/tests/v2/devfiles/samples/Test_Parent_LocalURI.yaml b/tests/v2/devfiles/samples/Test_Parent_LocalURI.yaml new file mode 100644 index 00000000..8e112b24 --- /dev/null +++ b/tests/v2/devfiles/samples/Test_Parent_LocalURI.yaml @@ -0,0 +1,95 @@ +schemaVersion: 2.1.0 +parent: + uri: "Parent.yaml" + commands: + - apply: + component: testcontainer1 #override, point to a container in the main devfile + group: + kind: test + isDefault: false #override + label: testcontainerparent #override + id: testapplyparentcommand1 + - id: run + exec: + component: testcontainerparent1 + commandLine: npm install #override + workingDir: /project2 #override + env: #addition, does not exist in parent + - name: PATH + value: /dir + - name: USER + value: user1 + group: + kind: build #override + isDefault: false #override + hotReloadCapable: false #override + - id: test + composite: + commands: [testapplyparentcommand1, run] #override + group: + kind: debug + label: testcompositeparent1 + parallel: false #override + components: + - kubernetes: + inlined: | #override + apiVersion: batch/v1 + kind: Pod + metadata: + name: pi + namespace: dev + spec: + template: + spec: + containers: + - name: newJob + image: myimage + command: ["some", "command"] + restartPolicy: Never + name: testkubeparent1 + - openshift: + uri: openshift2.yaml #override + name: openshiftcomponent1 + - container: + image: updatedimage #override + name: testcontainerparent1 + projects: + - name: petclinic + git: + remotes: + neworigin: "https://github.com/spring-projects/spring-petclinic2.git" #override, should result in 2 remotes in flattened file + checkoutFrom: + remote: neworigin #override + revision: master #override + - name: petclinic-dev + zip: + location: https://github.com/spring-projects/spring-petclinic/petclinic.zip #override + clonePath: /petclinic #overrides the default + attributes: + editorFree: false #override + user: user1 #override + starterProjects: + - name: user-app + git: + remotes: + origin: 'https://github.com/OpenLiberty/application-stack-starters-new.git' #override + description: An Open Liberty Starter project override #override + subDir: /newapp #override + attributes: #add additional attributes + env: test + user: user1 + attributes: # only applicable to v2.1.0 + category: mainDevfile #override + title: This is a main devfile #override + variables: #only applicable to v2.1.0 + version: 2.1.0 #override + tag: main #override + lastUpdated: "2021" #override +components: +- container: + image: mKrpiOQnyGZ00003 + name: testcontainer1 + + + + diff --git a/tests/v2/devfiles/samples/Test_Parent_RegistryURL.yaml b/tests/v2/devfiles/samples/Test_Parent_RegistryURL.yaml new file mode 100644 index 00000000..deea655a --- /dev/null +++ b/tests/v2/devfiles/samples/Test_Parent_RegistryURL.yaml @@ -0,0 +1,29 @@ +schemaVersion: 2.1.0 +parent: + id: nodejs + registryUrl: "https://registry.stage.devfile.io" + commands: + - id: run + exec: + component: runtime + commandLine: npm install #override + workingDir: /project2 #override + components: + - name: runtime + container: + image: registry.access.redhat.com/ubi8/nodejs-14:dev #override + memoryLimit: 2048Mi #override + mountSources: false #override + sourceMapping: /project2 #override + endpoints: + - name: http-9080 #this will result in a second endpoint + targetPort: 9080 + starterProjects: + - name: nodejs-starter + git: + remotes: + origin: "https://github.com/odo-devfiles/nodejs-ex2.git" #override + + + + diff --git a/tests/v2/libraryTest/library_test.go b/tests/v2/libraryTest/library_test.go index bbbf9815..dbe4296e 100644 --- a/tests/v2/libraryTest/library_test.go +++ b/tests/v2/libraryTest/library_test.go @@ -1,11 +1,16 @@ package api import ( + "context" "testing" schema "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" + "github.com/devfile/api/v2/pkg/attributes" commonUtils "github.com/devfile/api/v2/test/v200/utils/common" + "github.com/devfile/library/pkg/devfile/parser" + "github.com/devfile/library/pkg/testingutil" libraryUtils "github.com/devfile/library/tests/v2/utils/library" + kubev1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_ExecCommand(t *testing.T) { @@ -207,12 +212,141 @@ func Test_MetadataEdit(t *testing.T) { libraryUtils.RunMultiThreadTest(testContent, t) } +func Test_Parent_Local_URI(t *testing.T) { + testContent := commonUtils.TestContent{} + testContent.AddParent = true + testContent.EditContent = false + testContent.FileName = "Test_Parent_LocalURI.yaml" + //copy the parent and main devfile from devfiles/samples + libraryUtils.CopyDevfileSamples(t, []string{testContent.FileName, "Parent.yaml"}) + libraryUtils.RunParentTest(testContent, t) + libraryUtils.RunMultiThreadedParentTest(testContent, t) +} + +//Create kube client and context and set as ParserArgs for Parent Kubernetes reference test. Corresponding main devfile is ../devfile/samples/TestParent_KubeCRD.yaml +func setClientAndContextParserArgs() *parser.ParserArgs { + name := "testkubeparent1" + parentSpec := schema.DevWorkspaceTemplateSpec{ + DevWorkspaceTemplateSpecContent: schema.DevWorkspaceTemplateSpecContent{ + Commands: []schema.Command{ + { + Id: "applycommand", + CommandUnion: schema.CommandUnion{ + Apply: &schema.ApplyCommand{ + Component: "devbuild", + LabeledCommand: schema.LabeledCommand{ + Label: "testcontainerparent", + BaseCommand: schema.BaseCommand{ + Group: &schema.CommandGroup{ + Kind: schema.TestCommandGroupKind, + IsDefault: true, + }, + }, + }, + }, + }, + }, + }, + Components: []schema.Component{ + { + Name: "devbuild", + ComponentUnion: schema.ComponentUnion{ + Container: &schema.ContainerComponent{ + Container: schema.Container{ + Image: "quay.io/nodejs-12", + }, + }, + }, + }, + }, + Projects: []schema.Project{ + { + Name: "parentproject", + ProjectSource: schema.ProjectSource{ + Git: &schema.GitProjectSource{ + GitLikeProjectSource: schema.GitLikeProjectSource{ + CheckoutFrom: &schema.CheckoutFrom{ + Revision: "master", + Remote: "origin", + }, + Remotes: map[string]string{"origin": "https://github.com/spring-projects/spring-petclinic.git"}, + }, + }, + }, + }, + { + Name: "parentproject2", + ProjectSource: schema.ProjectSource{ + Zip: &schema.ZipProjectSource{ + Location: "https://github.com/spring-projects/spring-petclinic.zip", + }, + }, + }, + }, + StarterProjects: []schema.StarterProject{ + { + Name: "parentstarterproject", + ProjectSource: schema.ProjectSource{ + Git: &schema.GitProjectSource{ + GitLikeProjectSource: schema.GitLikeProjectSource{ + CheckoutFrom: &schema.CheckoutFrom{ + Revision: "main", + Remote: "origin", + }, + Remotes: map[string]string{"origin": "https://github.com/spring-projects/spring-petclinic.git"}, + }, + }, + }, + }, + }, + Attributes: attributes.Attributes{}.FromStringMap(map[string]string{"category": "parentDevfile", "title": "This is a parent devfile"}), + Variables: map[string]string{"version": "2.0.0", "tag": "parent"}, + }, + } + testK8sClient := &testingutil.FakeK8sClient{ + DevWorkspaceResources: map[string]schema.DevWorkspaceTemplate{ + name: { + TypeMeta: kubev1.TypeMeta{ + APIVersion: "2.1.0", + }, + Spec: parentSpec, + }, + }, + } + parserArgs := parser.ParserArgs{} + parserArgs.K8sClient = testK8sClient + parserArgs.Context = context.Background() + return &parserArgs +} + +func Test_Parent_KubeCRD(t *testing.T) { + testContent := commonUtils.TestContent{} + testContent.AddParent = true + testContent.EditContent = false + testContent.FileName = "Test_Parent_KubeCRD.yaml" + parserArgs := setClientAndContextParserArgs() + libraryUtils.CopyDevfileSamples(t, []string{testContent.FileName}) + libraryUtils.SetParserArgs(*parserArgs) + libraryUtils.RunParentTest(testContent, t) + libraryUtils.RunMultiThreadedParentTest(testContent, t) +} + +func Test_Parent_RegistryURL(t *testing.T) { + testContent := commonUtils.TestContent{} + testContent.AddParent = true + testContent.EditContent = false + testContent.FileName = "Test_Parent_RegistryURL.yaml" + libraryUtils.CopyDevfileSamples(t, []string{testContent.FileName}) + libraryUtils.RunParentTest(testContent, t) + libraryUtils.RunMultiThreadedParentTest(testContent, t) +} + func Test_Everything(t *testing.T) { testContent := commonUtils.TestContent{} - testContent.CommandTypes = []schema.CommandType{schema.ExecCommandType, schema.CompositeCommandType, schema.ApplyCommandType} - testContent.ComponentTypes = []schema.ComponentType{schema.ContainerComponentType, schema.KubernetesComponentType, schema.OpenshiftComponentType, schema.VolumeComponentType} - testContent.ProjectTypes = []schema.ProjectSourceType{schema.GitProjectSourceType, schema.ZipProjectSourceType} - testContent.StarterProjectTypes = []schema.ProjectSourceType{schema.GitProjectSourceType, schema.ZipProjectSourceType} + testContent.CommandTypes = commonUtils.CommandTypes + testContent.ComponentTypes = commonUtils.ComponentTypes + testContent.ProjectTypes = commonUtils.ProjectSourceTypes + testContent.StarterProjectTypes = commonUtils.ProjectSourceTypes testContent.AddEvents = true testContent.AddMetaData = true testContent.EditContent = false @@ -224,10 +358,10 @@ func Test_Everything(t *testing.T) { func Test_EverythingEdit(t *testing.T) { testContent := commonUtils.TestContent{} - testContent.CommandTypes = []schema.CommandType{schema.ExecCommandType, schema.CompositeCommandType, schema.ApplyCommandType} - testContent.ComponentTypes = []schema.ComponentType{schema.ContainerComponentType, schema.KubernetesComponentType, schema.OpenshiftComponentType, schema.VolumeComponentType} - testContent.ProjectTypes = []schema.ProjectSourceType{schema.GitProjectSourceType, schema.ZipProjectSourceType} - testContent.StarterProjectTypes = []schema.ProjectSourceType{schema.GitProjectSourceType, schema.ZipProjectSourceType} + testContent.CommandTypes = commonUtils.CommandTypes + testContent.ComponentTypes = commonUtils.ComponentTypes + testContent.ProjectTypes = commonUtils.ProjectSourceTypes + testContent.StarterProjectTypes = commonUtils.ProjectSourceTypes testContent.AddEvents = true testContent.AddMetaData = true testContent.EditContent = true diff --git a/tests/v2/utils/library/test_utils.go b/tests/v2/utils/library/test_utils.go index 57e8d28b..88c35c6a 100644 --- a/tests/v2/utils/library/test_utils.go +++ b/tests/v2/utils/library/test_utils.go @@ -3,6 +3,7 @@ package utils import ( "errors" "fmt" + "os" "strconv" "strings" "testing" @@ -10,13 +11,13 @@ import ( schema "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" header "github.com/devfile/api/v2/pkg/devfile" + commonUtils "github.com/devfile/api/v2/test/v200/utils/common" devfilepkg "github.com/devfile/library/pkg/devfile" "github.com/devfile/library/pkg/devfile/parser" devfileCtx "github.com/devfile/library/pkg/devfile/parser/context" devfileData "github.com/devfile/library/pkg/devfile/parser/data" "github.com/devfile/library/pkg/devfile/parser/data/v2/common" - - commonUtils "github.com/devfile/api/v2/test/v200/utils/common" + "github.com/devfile/library/pkg/util" ) const ( @@ -30,6 +31,11 @@ const ( // The DevfileValidator interface is test/v200/utils/common/test_utils.go of the devfile/api repository. type DevfileValidator struct{} +var parserArgs = parser.ParserArgs{} + +//directory where test devfiles are generated and/or copied +const destDir = "tmp/library_test/" + // WriteAndValidate implements DevfileValidator interface. // writes to disk and validates the specified devfile func (devfileValidator DevfileValidator) WriteAndValidate(devfile *commonUtils.TestDevfile) error { @@ -131,7 +137,7 @@ func (devfileFollower DevfileFollower) UpdateMetaData(updateMetaData header.Devf devfileFollower.LibraryData.SetMetadata(updateMetaData) } -// SetMetaData sets the specified schemaVersion in the library data +// SetSchemaVersion sets the specified schemaVersion in the library data func (devfileFollower DevfileFollower) SetSchemaVersion(schemaVersion string) { devfileFollower.LibraryData.SetSchemaVersion(schemaVersion) } @@ -172,9 +178,16 @@ func validateDevfile(devfile *commonUtils.TestDevfile) error { var err error commonUtils.LogInfoMessage(fmt.Sprintf("Parse and Validate %s : ", devfile.FileName)) - libraryObj, err := devfilepkg.ParseAndValidate(devfile.FileName) + + parserArgs.Path = devfile.FileName + libraryObj, warning, err := devfilepkg.ParseDevfileAndValidate(parserArgs) + + if len(warning.Commands) > 0 || len(warning.Components) > 0 || len(warning.Projects) > 0 || len(warning.StarterProjects) > 0 { + commonUtils.LogWarningMessage(fmt.Sprintf("top-level variables were not substituted successfully %+v\n", warning)) + } + if err != nil { - commonUtils.LogErrorMessage(fmt.Sprintf("From ParseAndValidate %v : ", err)) + commonUtils.LogErrorMessage(fmt.Sprintf("From ParseDevfileAndValidate %v : ", err)) } else { follower := devfile.Follower.(DevfileFollower) follower.LibraryData = libraryObj.Data @@ -189,13 +202,10 @@ func RunMultiThreadTest(testContent commonUtils.TestContent, t *testing.T) { commonUtils.LogMessage(fmt.Sprintf("Start Threaded test for %s", testContent.FileName)) devfileName := testContent.FileName - var i int - for i = 1; i < numThreads; i++ { + for i := 1; i < numThreads; i++ { testContent.FileName = commonUtils.AddSuffixToFileName(devfileName, "T"+strconv.Itoa(i)+"-") go RunTest(testContent, t) } - testContent.FileName = commonUtils.AddSuffixToFileName(devfileName, "T"+strconv.Itoa(i)+"-") - RunTest(testContent, t) commonUtils.LogMessage(fmt.Sprintf("Sleep 3 seconds to allow all threads to complete : %s", devfileName)) time.Sleep(3 * time.Second) @@ -203,11 +213,65 @@ func RunMultiThreadTest(testContent commonUtils.TestContent, t *testing.T) { } +// RunMultiThreadedParentTest : Runs the same test on multiple threads, the test is based on the content of the specified TestContent +func RunMultiThreadedParentTest(testContent commonUtils.TestContent, t *testing.T) { + + commonUtils.LogMessage(fmt.Sprintf("Start Threaded parent test for %s", testContent.FileName)) + devfileName := testContent.FileName + for i := 1; i < numThreads+1; i++ { + testContent.FileName = commonUtils.AddSuffixToFileName(devfileName, "T"+strconv.Itoa(i)+"-") + duplicateDevfileSample(t, devfileName, testContent.FileName) + go RunParentTest(testContent, t) + } + + commonUtils.LogMessage(fmt.Sprintf("Sleep 3 seconds to allow all threads to complete : %s", devfileName)) + time.Sleep(3 * time.Second) + commonUtils.LogMessage(fmt.Sprintf("Sleep complete : %s", devfileName)) + +} + +// SetParserArgs : Used when parser args other than filename are set in the library tests +func SetParserArgs(args parser.ParserArgs) { + parserArgs = args +} + +// CopyDevfileSamples : Copies existing artifacts from the devfiles/samples directory to the tmp/library_test directory. Used in parent tests +func CopyDevfileSamples(t *testing.T, testDevfiles []string) { + + srcDir := "../devfiles/samples/" + dstDir := commonUtils.CreateTempDir("library_test") + + for i := range testDevfiles { + srcPath := srcDir + testDevfiles[i] + destPath := dstDir + testDevfiles[i] + + file, err := os.Stat(srcPath) + if err != nil { + t.Fatalf(commonUtils.LogErrorMessage(fmt.Sprintf("Error locating testDevfile %v ", err))) + } else { + commonUtils.LogMessage(fmt.Sprintf("copy file from %s to %s ", srcPath, destPath)) + util.CopyFile(srcPath, destPath, file) + } + } +} + +//duplicateDevfileSample: Makes a copy of the parent devfile test artifact that is expected to exist in the tmp/library_test directory. +//This is used in the multi-threaded parent test scenarios +func duplicateDevfileSample(t *testing.T, src string, dst string) { + srcPath := destDir + src + destPath := destDir + dst + file, err := os.Stat(srcPath) + if err != nil { + t.Fatalf(commonUtils.LogErrorMessage(fmt.Sprintf("Error locating testDevfile %v ", err))) + } else { + commonUtils.LogMessage(fmt.Sprintf("duplicate file %s to %s ", srcPath, destPath)) + util.CopyFile(srcPath, destDir+dst, file) + } +} + // RunTest : Runs a test to create and verify a devfile based on the content of the specified TestContent func RunTest(testContent commonUtils.TestContent, t *testing.T) { - commonUtils.LogMessage(fmt.Sprintf("Start test for %s", testContent.FileName)) - devfileName := testContent.FileName for i := 1; i <= numDevfiles; i++ { @@ -262,6 +326,20 @@ func RunTest(testContent commonUtils.TestContent, t *testing.T) { } } +//RunParentTest : Runs parent tests based on pre-existing artifacts +func RunParentTest(testContent commonUtils.TestContent, t *testing.T) { + commonUtils.LogMessage(fmt.Sprintf("Start test for %s", testContent.FileName)) + follower := DevfileFollower{} + validator := DevfileValidator{} + testfileName := destDir + testContent.FileName + testDevfile, _ := commonUtils.GetDevfile(testfileName, follower, validator) + testDevfile.SchemaDevFile.Parent = &schema.Parent{} + err := validateDevfile(&testDevfile) + if err != nil { + t.Fatalf(commonUtils.LogErrorMessage(fmt.Sprintf("Error validating testDevfile %v ", err))) + } +} + // verify verifies the library contents of the specified devfile with the expected content func verify(devfile *commonUtils.TestDevfile) error {