diff --git a/test/e2e/framework/testfiles/testdata/a/foo.txt b/test/e2e/framework/testfiles/testdata/a/foo.txt new file mode 100644 index 00000000000..557db03de99 --- /dev/null +++ b/test/e2e/framework/testfiles/testdata/a/foo.txt @@ -0,0 +1 @@ +Hello World diff --git a/test/e2e/framework/testfiles/testfiles.go b/test/e2e/framework/testfiles/testfiles.go index a0251abfbab..2d45d9fd119 100644 --- a/test/e2e/framework/testfiles/testfiles.go +++ b/test/e2e/framework/testfiles/testfiles.go @@ -25,8 +25,10 @@ limitations under the License. package testfiles import ( + "embed" "errors" "fmt" + "io/fs" "io/ioutil" "os" "path" @@ -176,3 +178,48 @@ func (b BindataFileSource) DescribeFiles() string { description := strings.Join(lines, "\n ") return description } + +// EmbeddedFileSource handles files stored in a package generated with bindata. +type EmbeddedFileSource struct { + EmbeddedFS embed.FS + Root string + fileList []string +} + +// ReadTestFile looks for an embedded file with the given path. +func (e EmbeddedFileSource) ReadTestFile(filepath string) ([]byte, error) { + relativePath := strings.TrimPrefix(filepath, fmt.Sprintf("%s/", e.Root)) + + b, err := e.EmbeddedFS.ReadFile(relativePath) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } + return nil, err + } + + return b, nil +} + +// DescribeFiles explains that it is looking inside an embedded filesystem +func (e EmbeddedFileSource) DescribeFiles() string { + var lines []string + lines = append(lines, "The following files are embedded into the test executable:") + + if len(e.fileList) == 0 { + e.populateFileList() + } + lines = append(lines, e.fileList...) + + return strings.Join(lines, "\n\t") +} + +func (e *EmbeddedFileSource) populateFileList() { + fs.WalkDir(e.EmbeddedFS, ".", func(path string, d fs.DirEntry, err error) error { + if !d.IsDir() { + e.fileList = append(e.fileList, filepath.Join(e.Root, path)) + } + + return nil + }) +} diff --git a/test/e2e/framework/testfiles/testfiles_test.go b/test/e2e/framework/testfiles/testfiles_test.go new file mode 100644 index 00000000000..71a69bafe44 --- /dev/null +++ b/test/e2e/framework/testfiles/testfiles_test.go @@ -0,0 +1,63 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testfiles + +import ( + "embed" + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + fooContents = `Hello World +` + fooPath = "testdata/a/foo.txt" + + notExistsPath = "testdata/b" + + expectedDescription = `The following files are embedded into the test executable: + testdata/a/foo.txt` +) + +//go:embed testdata/a +var testFS embed.FS + +func getTestEmbeddedSource() *EmbeddedFileSource { + return &EmbeddedFileSource{ + EmbeddedFS: testFS, + } +} + +func TestEmbeddedFileSource(t *testing.T) { + s := getTestEmbeddedSource() + + // read a file which exists and compare the contents + b, err := s.ReadTestFile(fooPath) + + assert.NoError(t, err) + assert.Equal(t, fooContents, string(b)) + + // read a non-existent file and ensure that the returned value is empty and error is nil + // Note: this is done so that the next file source can be tried by the caller + b, err = s.ReadTestFile(notExistsPath) + assert.NoError(t, err) + assert.Empty(t, b) + + // describing the test filesystem should list down all files + assert.Equal(t, expectedDescription, s.DescribeFiles()) +}