-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: 'go test' fails to cache test result due to modified .git
directory
#52573
Comments
Narrowing it down a bit further, I ran Here's a diff between runs. The modtime changes everytime. HASH[open]: "go1.18"
HASH[open]: "stat 160 800001ed 2022-04-26 12:07:04.587272446 -0500 CDT true\n"
HASH[open]: "file .git "
- HASH[open]: "stat 288 800001ed 2022-04-26 12:07:22.744082806 -0500 CDT true\n"
+ HASH[open]: "stat 288 800001ed 2022-04-26 12:07:42.335762299 -0500 CDT true\n"
HASH[open]: "file go.mod "
HASH[open]: "stat 58 1a4 2022-04-26 11:34:12.067721337 -0500 CDT false\n"
HASH[open]: "file one_test.go "
HASH[open]: "stat 144 1a4 2022-04-26 11:53:56.630154997 -0500 CDT false\n"
- HASH[open]: 8e895090d73fda1474da8cd9819d3196677d2ffd2cc3e6f7a401b2c6cc09abf4
- HASH[testInputs]: "open /Users/m/dev/src/github.com/matthewmueller/hack/test-cache 8e895090d73fda1474da8cd9819d3196677d2ffd2cc3e6f7a401b2c6cc09abf4\n"
- HASH[testInputs]: 397c0fa5c27c402f4b5be6f2ce32780bbb718ae956556f493dc111fb38089581
+ HASH[open]: 53356a05f8ddd1917cffb837b75f5de58859b18675069e571929e60b2ff7aa5e
+ HASH[testInputs]: "open /Users/m/dev/src/github.com/matthewmueller/hack/test-cache 53356a05f8ddd1917cffb837b75f5de58859b18675069e571929e60b2ff7aa5e\n"
+ HASH[testInputs]: c43d67ffb3fff2baa47ae3a2caef13367214dcf1f3217124453bc035daa4db87 It looks like the logic is in here: go/src/cmd/go/internal/test/test.go Line 1742 in 1158520
|
can you try -buildvcs=false and/or 1.18.1? |
Update: could be related to my Edit: thanks for the message @seankhliao, I'll try that next if my current lead doesn't pan out. |
Welp, that was a tough one, it was related to my git prompt. # Add git to the terminal prompt
git_prompt() {
# Don't go any further if we're not in a git repo
# git rev-parse --is-inside-work-tree &> /dev/null || return
# Stylize
echo -n "$color_red"
# echo -n "$(git_branch)"
echo -n "$color_reset"
echo -n "$color_purple"
# echo -n "$(git_progress)"
echo -n "$color_reset"
echo -n "$color_yellow"
echo -n "$(git_dirty)"
echo -n "$color_reset"
}
# fastest possible way to check if repo is dirty
git_dirty() {
# If the git status has *any* changes (e.g. dirty), echo our character
if [[ -n "$(git status --porcelain 2> /dev/null)" ]]; then
echo " !"
fi
} It appears that Thanks for suggestion @seankhliao! |
I'd actually like to re-open this one, but perhaps more like a feature request. Why is I might be missing something but I'd expect go test to cache to work something like this: "Walk the Go files starting from the test, then its imports, imports of imports, hashing all the files it encounters. Now that we have embedded files, we can discover those as well". A similar solution is how I can share more code but something here's the recursive function to hopefully show what I mean: func findDeps(fset *fileSet, module *gomod.Module, dir string) (err error) {
imported, err := build.Default.Import(".", dir, build.ImportMode(0))
if err != nil {
return err
}
// Add all the Go files
for _, path := range imported.GoFiles {
fset.Add(filepath.Join(dir, path))
}
// Add all the embeds
// TODO: resolve patterns
for _, path := range imported.EmbedPatterns {
fset.Add(filepath.Join(dir, path))
}
// Traverse imports and compute a hash
eg := new(errgroup.Group)
for _, importPath := range imported.Imports {
importPath := importPath
eg.Go(func() error {
if !shouldWalk(module, importPath) {
return nil
}
dir, err := module.ResolveDirectory(importPath)
if err != nil {
return err
}
relPath, err := filepath.Rel(module.Directory(), dir)
if err != nil {
return err
}
if err := findDeps(fset, module, relPath); err != nil {
return err
}
return nil
})
}
return eg.Wait()
} Feel free to close again or I can open a different issue. Just after spending some time debugging the test cache, it feels like it could be a lot faster. |
The The @matthewmueller, does that explain the behavior you were seeing? Is there anything left to be done here? |
.git
directory
Thanks for the response @bcmills! Yep, I eventually learned that The reason I re-opened this is because I still wonder: Why does While the above seems wasteful, it isn't my top-level problem. My top-level problem is that by considering all these files in the caching decision, the setup and tear down of these tests take longer than the test itself. I commented on that in this issue. |
Your test results may depend on the result of |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
This took me awhile to whittle down. My tests were running unbearably slow and never seeming to cache. I'm still investigating the slowness (this issue describes the symptoms), but I'm able to reproduce the caching issue:
1. Create the following directory tree:
With the following
one_test.go
:go mod init
git init
go test ./one_test.go
multiple timesWhat did you expect to see?
I expected to see it cache after the second run:
What did you see instead?
It never caches. If you remove
.git
it will start caching again. Oddly adding other types of directories likea/b
or.a/b
still cache. It seems there's something special with.git
.Why do you need this?
My test suite needs to lookup the
go.mod
of the current project directory. With this logic in place, my tests never cache.The text was updated successfully, but these errors were encountered: