https://golang.org/pkg/context/ is clear on the topic of storing a context.Context in a struct: "Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter, typically named ctx:"
When I added the testing.State struct, I thought that it was a special case since it's passed into test functions and doesn't outlive any individual test, so I went ahead and made it store a context (two contexts, actually) and expose a Context() function that tests can call.
I'm starting to think that that was a mistake, though. We now pass the same testing.State to several different functions (test functions, setup functions, cleanup functions), and as a result, they all share the same context and the same deadline. It's likely that we'll want to pass it to even more places in the future (e.g. preconditions). I think we need the ability to pass different contexts in different places.
I've also noticed that many (most?) tests contain a statement like:
ctx := s.Context()
This suggests to me that the context is used frequently enough that it should be a test function argument, e.g.
func MyTest(ctx context.Context, s *testing.State) {
That saves a line of boilerplate in each test (at the cost of a longer function signature).
If we want to change this, it'll be somewhat painful, but I think it can be done relatively safely with the following steps:
a) Add a new field to testing.Test:
FuncCtx func(context.Context, *testing.State)
b) Update Test.Run to invoke FuncCtx instead of Func if the
former is non-nil, and to pass s.tctx to it.
c) Update all tests to set FuncCtx instead of Func.
d) Update Test.Func to also take a context.
e) Update tests to set Func instead of FuncCtx.
f) Delete FuncCtx and State.Context.
It would also be possible to just do it in two simultaneous changes to tast and tast-tests, but that would be dependent on nobody trying to add new tests and may be hard to land.
Does this sound reasonable?
Comment 1 by derat@chromium.org
, Sep 30