Skip to content
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

New test tooling #3418

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

apostasie
Copy link
Contributor

@apostasie apostasie commented Sep 7, 2024

We are not in a good situation wrt our testing. The build would be constantly red if it wasn't for the fact we are retrying every test multiple times. Some of it may be bugs, but most of it is definitely broken tests.

Despite lengthy efforts to reduce flakiness one by one, it seems unlikely to me that we can make significant progress without better test tooling to use.

This here proposes a new testing approach that should hopefully address our endemic issues and promote better testing in the future, by providing by default better test isolation, simpler, more debuggable helpers, and overall a more expressive testing approaching.

Commit 1 is the tooling itself.

Commit 2 is a handful of tests being rewritten with the new tooling.

Commit 3 is documentation.

Background information:

Obviously, this should keep evolving a lot, and some stuff might have to change as we rewrite more tests and discover more use-cases.

I would suggest reading the testtool.md doc first before engaging with code.

Right now, what matters most IMHO is that:

  • we agree on the problem statement - hopefully we do :-)
  • we are overall comfortable with the high-level goals and design approach (let's call it "table driven test++")
  • we find the proposed DX acceptable enough

Improvements can always follow.

@apostasie apostasie force-pushed the dev-3130-tesutil-nextgen branch 4 times, most recently from 8cb9f25 to 814418a Compare September 7, 2024 22:37
@apostasie apostasie force-pushed the dev-3130-tesutil-nextgen branch 4 times, most recently from 37bc5e9 to 193a67d Compare September 18, 2024 05:30
@apostasie apostasie changed the title [WIP] Test tooling refresh New test tooling Sep 18, 2024
@apostasie apostasie marked this pull request as ready for review September 18, 2024 05:34
@apostasie
Copy link
Contributor Author

@AkihiroSuda this is ready for a first review.

CI is pending.

WithConfig(key ConfigKey, value ConfigValue) Data
ReadConfig(key ConfigKey) ConfigValue

// Private methods
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private methods do not need to be defined in the interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do need getLabels and getConfig here:

func configureData(t *testing.T, seedData Data, parent Data) Data {
if seedData == nil {
seedData = &data{}
}
dat := &data{
config: seedData.getConfig(),
labels: seedData.getLabels(),

Will remove adopt, which is not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (removed adopt).

Lmk if there is a better way to achieve this without defining the other two on the interface.

"github.com/containerd/nerdctl/v2/pkg/inspecttypes/dockercompat"
"github.com/containerd/nerdctl/v2/pkg/inspecttypes/native"
"github.com/containerd/nerdctl/v2/pkg/testutil"
"github.com/containerd/nerdctl/v2/pkg/testutil/test"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why separate pkg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are nerdctl specific (NerdctlToml, etcetera). Motivation was that there is already a lot inside the test package, and the nerdtest package will likely grow a lot more as it subsumes base.

I can merge them back together though if preferable. No strong opinion here.

docs/dev/testtool.md Outdated Show resolved Hide resolved
@apostasie apostasie force-pushed the dev-3130-tesutil-nextgen branch 2 times, most recently from 6b60abc to 28263b1 Compare September 18, 2024 06:32
Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@AkihiroSuda AkihiroSuda added the area/ci e.g., CI failure label Sep 18, 2024
@apostasie
Copy link
Contributor Author

Thanks

@AkihiroSuda

I forgot to convert some tests that are commented out.
Let me take care of that ASAP before we merge.

@AkihiroSuda AkihiroSuda marked this pull request as draft September 18, 2024 23:44
Our testing tools have served us well, and there are plenty of good things with them that we absolutely need to keep.
We have grown a large test suite though, and the sheer size of it is putting pressure on it and it is
starting to show cracks.
Besides bugs per-se (double execution) - that we hopefully fixed - our design is reaching its limits.
We do have rather impactful issues with regard to test isolation and test concurrency, leading to situations where
it is hard or outright impossible to figure out which test is causing a cascading failure, or why the adding of a new test
file working individually breaks everything.

Furthermore, as we are not prescriptive on certain things, we do see a lot of negative patterns emerging from test authors:
- defer being used instead of t.Cleanup
- not calling cleanup routines before running tests
- outright forgetting to cleanup resources
- Cwd for binary calls is by default the current working directory of the test process - this is causing a variety of issues,
as it could very well be read-only (lima), and should by default be a temp directory
- manipulating the environment directly - which has side-effects for other tests
- tests becoming big blurbs of mixed together setup, cleanup, and actual test routines - making them hard to read and figuring
out what is actually being tested
- subtests repetitiveness w. shadowing testutil.T leading to confusing code
- ... or not dereferencing the current test in a loop
- in-test homegrown abstractions being inherently repetitive, with the same boilerplate over and over again
- structuring tests and subtests being left as an exercise to the developer - leading to a wide variety of approaches
and complex boilerplate
- hard to debug: a lot of the assert methods do not provide any feedback whatsoever on what was the command that actually
failed, or what was the output, or environment of it
- icmd.Expected showing its limits, and making assumptions that there is only one error you can test, or that you can only
test the output if exitCode == 0
- running commands with other binaries than the current target (eg: not calling base.Cmd) being left as an exercise
to the developer, leading to all of the issues above (Chdir, Env manipulation, no debugging output, etc)
- no-parallel being the default - unless specified otherwise - which should be the other way around
- very rarely testing stderr in case of error - partly because we do not use typed errors, but also because it is
cumbersome / not obvious / limited

This new tooling offers a set of abstractions that should address all of these and encourage more expressive, better structured,
better isolated, more debuggable tests.

Signed-off-by: apostasie <[email protected]>
@apostasie
Copy link
Contributor Author

apostasie commented Sep 19, 2024

@AkihiroSuda last push finish converting and re-enabled the mistakenly commented out tests.
Apologies for missing it.

Also note a small change in the test tooling, enabling Parallel for test.Group.

@apostasie apostasie marked this pull request as ready for review September 19, 2024 23:02
@apostasie
Copy link
Contributor Author

CI failures are network flukes, which have been endemic with github recently.
Concerning for sure, but unrelated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ci e.g., CI failure
Projects
None yet
Development

Successfully merging this pull request may close these issues.

testutil helpers are hard to use and make too many assumptions on command outcomes
2 participants