ginkgo
ginkgo copied to clipboard
Support go:embed directive in ginkgo build
Hi ginkgo folks,
love your go bdd framework and have a feature request (or documentation request, if already available). We use the Golang embed directive to create an embedded filesystem and store some test environment specific properties there. But the ginkgo build does not seem to pack it into the binary generated with "ginkgo build
Best regards and happy coding
Marius
hey @MariusSchmidt - glad you're enjoying Ginkgo :)
ginkgo build
is simply using go test -c
under the hood. Can you do me a favor and check wether or not simply running go test -c
results in different behavior? Also do you see embed
work when you run ginkgo
(ie is the issue only occurring if you use ginkgo build
? or does it always happen?)
I'll try to do some debugging myself when im next at my machine.
I've used go:embed
with files (not directories) in Ginkgo and it worked fine. Do you have any more detail on the issues that you're seeing? Can you make it work outside Ginkgo?
Hi @onsi and hi @blgm ,
Your answers been helpful. Onsi you might want to add to the documentation, that gingko build basically calls go test -c. I debugged it using the "go test" build, to ensure it is not something weird with ginkgo build and found out, that I slightly misused the embed feature. For reference
What I did before (WRONG):
// Adds preconfigured environment properties to an embedded filesystem
//go:embed env
var envs embed.FS
func loadFromPropertyFiles(envName string) map[string]string {
s := make(map[string]string)
_ = fs.WalkDir(envs, "env/"+envName, func(path string, d fs.DirEntry, walkError error) error {
if walkError == nil && !d.IsDir() && strings.HasSuffix(d.Name(), ".properties") {
bytes, fileReadError := ioutil.ReadFile(path)
if fileReadError != nil {
log.Printf("Unable to process file path '%s'", path)
return fileReadError
}
props := parsePropertiesFile(string(bytes[:]))
mergeMaps(s, props)
}
return nil
})
return s
}
The problem is in the line with "ioutil.ReadFile(path)". Calling it that way, in my understanding, I trigger a ReadFile from the OS and not from the embedded fs.
This is, how it works now. As one might spot, we need to use the ReadFile method from the embed.FS stored in 'envs' in my case:
// Adds preconfigured environment properties to an embedded filesystem
//go:embed env
var envs embed.FS
func loadFromPropertyFiles(envName string) map[string]string {
s := make(map[string]string)
_ = fs.WalkDir(envs, "env/"+envName, func(path string, d fs.DirEntry, walkError error) error {
if walkError == nil && !d.IsDir() && strings.HasSuffix(d.Name(), ".properties") {
bytes, fileReadError := envs.ReadFile(path)
if fileReadError != nil {
log.Printf("Unable to process file path '%s'", path)
return fileReadError
}
props := parsePropertiesFile(string(bytes[:]))
mergeMaps(s, props)
}
return nil
})
return s
}
The ability to compile the test suite into a single and self-contained binary is double awesome. Because what we want to do is, to ship test-containers alongside the product. So everybody has a versioned test tool at hand to verify, that the current installation is working. If you are interested, I did this with Gauge Testing before and am currently porting the same idea to Go + Ginkgo https://denktmit.de/2021/11/21/release-and-ship-your-e2e-tests-as-containers-alongside-your-product.html
Best regards, thanks for a cool testing tool and nice documentation