Closed myitcv closed 6 years ago
/cc @rsc @bcmills
I guess probably "all" should exclude the standard library (in all commands not just go test
), on the theory that it's already tested, not subject to vendoring, and so on. It's a little weird to special case it but it really is special.
Should ...
patterns also exclude the standard library in module mode? (modload.ImportPaths
currently implements all
in terms of ...
.)
Actually, there is currently a special postprocessing phase for all
, so it seems that if we make a minimal change then patterns involving ...
will continue to match the standard library.
Still, it seems like an interesting edge-case to consider.
I stand corrected again. Patterns involving ...
already do not match the standard library in module mode.
Change https://golang.org/cl/125835 mentions this issue: cmd/go:/internal/modload: omit the standard library from "all"
Per discussion on https://golang.org/cl/125835, I think this is working as intended: "all" should include the subset of the standard library that is actually (transitively) imported by the current module.
To test all packages in the current module and its submodules, you can execute go test ./...
from the module root, or go test $(go list -m)/...
from anywhere in the module.
It's true that we don't have a good pattern for “exactly the packages in the current module”, but all
is not that pattern.
Per discussion on https://golang.org/cl/125835, I think this is working as intended: "all" should include the subset of the standard library that is actually (transitively) imported by the current module.
Thanks. What I was after was a way of testing all packages in the current module and the transitive closure of package dependencies, excluding the standard library, i.e.
go test $(go list -f "{{if not .Standard}}{{.ImportPath}}{{end}}" $(go list -f '{{ join .Deps "\n"}}' $(go list -m)/...) $(go list -m)/...)
Edit: updated command to include $(go list -m)/...
argument to go test
Reason being, it's probably safe to assume that the standard library packages I'm using (transitively) are already tested 😄. Build caching would obviate this concern to an extent, but I'd still have to run the tests for a standard library package once per release... but then that's already been done for me. Unless I'm missing something here about the benefit of (re)testing and hence including standard library packages in this definition?
To test all packages in the current module and its submodules, you can execute go test ./... from the module root, or go test $(go list -m)/... from anywhere in the module.
I don't think ./...
includes submodules, does it? Since https://go-review.googlesource.com/c/vgo/+/122397, ./...
has explicitly excluded submodules. For the reason that a subdirectory is not guaranteed to be a submodule.
However ./...
being defined as such is somewhat unhelpful when it is the case that subdirectories are submodules (e.g. CI testing of a mono-repo). For now I've resorted to using find -name go.mod
... because I realise this is probably something of an edge case, at least for Go 1.11.
It's true that we don't have a good pattern for “exactly the packages in the current module”, but all is not that pattern.
Given the above, I think m/...
does actually cover this, because it doesn't recurse into submodules.
We do have kind of a weird inconsistency here, though. all
applies to all modules and includes the standard library, but ...
applies to all modules but excludes the standard library. I don't see any way to list patterns within the standard library in module mode, but maybe that's just not a thing we need to support.
Change https://golang.org/cl/128637 mentions this issue: cmd/go: test package patterns with multiple modules
It's a pity we staying with the behaviour go test all
testing std lib.
From https://research.swtch.com/vgo-tour:
Of course, after an upgrade, it's a good idea to test that everything still works. Our dependencies rsc.io/quote and rsc.io/sampler have not been tested with the newer text module. We can run their tests in the configuration we've created:
$ vgo test all
Guys, I believe we definitely need some short pattern to test the entire project with dependencies excluding std lib. Because as @myitcv mentioned, why should we ever test it if it's been already tested in Go release?
Patterns like go test $(go list -f "{{if not .Standard}}{{.ImportPath}}{{end}}" $(go list -f '{{ join .Deps "\n"}}' $(go list -m)/...))
look too clumsy, no one will be happy using such things in their project.
And the second reason for excluding std lib - some tests are very slow, I don't want to run them even once. Consider this small example (I still have go1.11beta2
, sorry):
cd `mktemp -d`
go mod -init -module example.com/hello
cat <<EOD >main.go
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
func main() {
addr := "localhost:6060"
fmt.Printf("Listening at: %q\n", addr)
http.ListenAndServe(addr, nil)
}
EOD
go test all
? example.com/hello [no test files]
ok fmt 0.142s
ok net/http 46.180s
ok net/http/pprof 2.200s
ok errors 0.033s
ok io 0.061s
ok math 0.042s
ok os 19.777s
46 sec? 20 sec? Guys, really? I see it and I just want to cancel :)
And signal.test
runs almost forever eating all CPU :(
$ ps aux | grep signal
ikorolev 66777 185.8 0.0 4380320 1932 s009 R+ 2:58PM 12:51.24 /var/folders/_b/d1934m9s587_8t_6ngv3hnc00000gp/T/go-build777311748/b810/signal.test -test.testlogfile=/var/folders/_b/d1934m9s587_8t_6ngv3hnc00000gp/T/go-build777311748/b810/testlog.txt
PS Just tried to run it on go1.11beta3
, got an error:
$ go test all
build fmt_test: cannot find module for path fmt_test
Maybe it's connected with #26722 and fixed on tip. Will check
Yeap, working on tip.
Actually I can't understand why the tests are so slow. If the tests are run when building go from source they are much faster:
ok net 1.985s
ok net/http 4.355s
ok net/http/cgi 0.684s
ok net/http/cookiejar 0.028s
ok net/http/fcgi 0.023s
ok net/http/httptest 0.042s
ok net/http/httptrace 0.019s
ok net/http/httputil 0.061s
ok net/http/internal 0.015s
ok net/http/pprof 2.032s
$ time go test net/http
ok net/http 40.735s
go test net/http 4.84s user 2.45s system 17% cpu 41.623 total
Why are the same tests so much faster when building go vs go test net/http
?
Anyway with so slow stdlib tests go test all
seems to be useless :(
This is the full timing of go test all
for the same example project:
$ time go test all
...
*** Test killed: ran too long (10m0s).
FAIL os/signal 605.012s
...
go test all 1521.37s user 69.95s system 228% cpu 11:35.33 total
Strange thing that testing os/signal
fails on my machine. Though it passes when building go. And it passes in go 1.10.3
I'll file a separate issue for that.
Anyway, if we don't count the os/signal
stuff, the longest tests taking >10s are:
ok net/http 44.172s
ok os 18.907s
ok net 30.170s
ok runtime 176.980s
ok runtime/pprof 42.158s
ok runtime/trace 10.776s
ok regexp 19.281s
ok compress/flate 11.576s
ok crypto/dsa 29.287s
Does it worth testing them at all?
@bcmills just to confirm my understanding (because this is the first time I'd seen the ...
in isolation, i.e. with no prefix):
go list ./... // all packages in the current directory and below,
// excluding modules in subdirectories (which may be submodules)
go list m/... // all packages in module m (by definition this does not
// include submodules)
go list ... // all packages in the current module and its module dependencies
go list all // the transitive set of package imports, including std lib
go test all // equivalent to go test $(go list all)
I don't see any way to list patterns within the standard library in module mode, but maybe that's just not a thing we need to support.
True, but we also don't have a way to easily list (and therefore test) the subset of go list all
that are not standard library packages. Rather selfishly, this is what I need now; I'm relying on the standard library tests already having been run.
I don't actually find go list ...
particularly useful. Let me demonstrate:
cd `mktemp -d`
export GOPATH=$(mktemp -d)
mkdir hello
cd hello
go mod init example.com/hello
cat <<EOD > main.go
package main
import _ "rsc.io/quote"
func main() {}
EOD
go list ...
gives:
Whereas what I'm actually interested in is (ignoring build constraints for now):
$ go list -f "{{if not .Standard}}{{.ImportPath}}{{end}}" $(go list -f '{{ join .Deps "\n"}}' $(go list -m)/...) $(go list -m)/...
golang.org/x/text/internal/tag
golang.org/x/text/language
rsc.io/quote
rsc.io/sampler
example.com/hello
The more I think about it, the more I think the current patterns are correct. Here's my reasoning:
all
is the pattern you want for guru
and other analysis tools. They need to scan and index the relevant parts of the standard library in order to make behaviors like “jump to definition” work uniformly....
is the pattern you want for pre-release testing. Your dependencies likely have a few integration tests, and for large integration tests, the packages that provide those integration tests might be distinct from the packages being tested. And integration tests are exactly the ones that are important to run when you're testing new combinations of dependency versions../...
is the pattern you want for day-to-day feature testing. You know your dependencies are fine, and you just want to re-test the module you're working on.So I think this is mostly just a documentation issue: we should be recommending go test ./...
or go test ...
, not go test all
.
@myitcv
go list ./... // all packages in the current directory and below, // excluding modules in subdirectories (which may be submodules)
Not just subdirectories, but excluding submodules in general (even if they aren't stored in subdirectories).
go list m/... // all packages in module m (by definition this does not // include submodules)
No, this one is “all packages in all modules with prefix
m/
”go list ... // all packages in the current module and its module dependencies go list all // the transitive set of package imports, including std lib
Yep.
go test all // equivalent to go test $(go list all)
Correct: go test <pattern>
should always be equivalent to go test $(go list <pattern>)
.
@bcmills
...
is the pattern you want for pre-release testing.
Is this really what you want for pre-release testing though? Because given my example in https://github.com/golang/go/issues/26317#issuecomment-411754782 this would involve me testing golang.org/x/tools/playground
which (amongst other packages in that list) is totally irrelevant unless I'm missing something obvious here?
Given that we don't have any other means to specify “package example.com/x/y
is an integration test for package example.com/z/w
”, I think so, yes. (Figuring out some sort of specification for that is a whole other can of worms.)
If caching is working properly, the overhead of “running” those tests should generally be fairly minimal — especially if we split the x/
repos into smaller modules and/or start giving more of them semantic version tags.
@bcmills
Given that we don't have any other means to specify “package example.com/x/y is an integration test for package example.com/z/w”, I think so, yes.
I see what I was missing, thanks.
(Figuring out some sort of specification for that is a whole other can of worms.)
True, but an interesting/worthwhile idea though.
split the x/ repos into smaller modules and/or start giving more of them semantic version tags.
Indeed.
In addition to this point, the bit I clearly forgot in all of this is the first line of go help modules
:
A module is a collection of related Go packages.
which helps to make more sense of the definition for ...
.
Thanks for taking the time to talk this through.
Do you want to leave this issue open in order to address:
So I think this is mostly just a documentation issue: we should be recommending
go test ./...
orgo test ...
, notgo test all
.
??
Will leave up to you.
The standard library is incorrectly excluded from ...
in module mode. It should be included.
We should be encouraging people to use all
to test the current module and its dependencies. Testing ...
instead will test lots of completely irrelevant packages. One of the main reasons for redefining all
was precisely to make it useful for go test [-short] all
.
We should be encouraging people to use
all
to test the current module and its dependencies.
@rsc do you mean we should exclude standard library from all
then? Otherwise it could be painful to use even with -short
mode on.
all means "all your dependencies - the things that actually get built into the packages in your modules". I don't see a compelling reason to exclude fmt if you use fmt but not exclude something else 10 levels down. Especially if you use -short, it should not be painful. And it should cache very well.
Thanks for the clarification!
OK, let's try to live with it. Only time could judge wether the community accepts this behaviour or not 😄
Maybe it's reasonable for a case, when there is really something wrong in your OS, making standard library tests to fail :) And it could help us to debug some crazy cases in future go releases.
I think this is now working as documented, so closing.
I'm on a very recent Macbook (Pro, 2018, 6 cores): Running go test std with GO111MODULE=on takes (even with everything cached):
real 1m43.740s
user 3m43.726s
sys 0m48.724s
because of
--- FAIL: TestCrashDumpsAllThreads (1.75s)
crash_unix_test.go:70: building source: exit status 1
go: cannot find main module; see 'go help modules'
FAIL
FAIL runtime 98.016s
Without the tests cached:
real 10m23.312s
user 27m35.928s
sys 1m34.860s
I think there's a bad assumption here that the std tests "should" always succeed (and that we can handwave them away with caching), because they do not, and from cold-start they are very time-consuming.
I'd like to do go test all as a quick check that everything I'm depending on works together, it's not convenient or a quick part of my workflow if it can blow out like this so easily.
I think there's a bad assumption here that the std tests "should" always succeed (and that we can handwave them away with caching), because they do not
If you find that a test in std
is consistently failing, please file an issue with steps to reproduce the failure.
Please answer these questions before submitting your issue. Thanks!
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
)?What did you do?
What did you expect to see?
I'm not totally clear what to expect because I couldn't see exactly where the special
all
argument is documented? But my guess is that it shouldn't include standard library packages.What did you see instead?