test/dnf-json: fix cleaning-up the cache after the test is finished

t.Parallel() makes defer weird. This commit moves the temporary dir setup
and teardown to the parallel subtest, so the teardown gets called after
the tests are finished.

More detailed explanation:

Consider this code:

```go
t.Run("group", func(t *testing.T) {
    setUp()
    t.Run("parallel test1", parallelTest1)
    t.Run("parallel test2", parallelTest1)
    t.Run("sequential test", sequentialTest)
    cleanUp()
})
```

When the group subtest is started, firstly parallelTest1 is run. When
t.Parallel() in the parallelTest1 is hit, its execution is suspended and
parallelTest2 is started. Once again, t.Parallel() is hit and the
parallelTest2 is suspended. Now, sequentialTest is started. It doesn't
contain t.Parallel() so it's run without any interruptions. The group subtest
continues its execution and calls the cleanUp method. After the cleanup is
done, the group subtest returns and it's time for the important part:
The parallelTest1 and 2 are resumed and run in parallel. In other words,
the code after t.Parallel is run when the PARENT subtest returns.

The important (and weird) part is that the parent subtest of the parallel
subtests returns before its parallel children finish. However, just the inner
anonymous function returns. The containing t.Run("group", func(){...})
function does not return until all the parallel subtests are finished.

How to solve this? One solution is to move the cleanup out of the group
subtest:

```go
t.Run("group", func(t *testing.T) {
    setUp()
    t.Run("parallel test1", parallelTest1)
    t.Run("parallel test2", parallelTest1)
    t.Run("sequential test", sequentialTest)

})
cleanUp()
```

How does this work? The group subtest is not marked as parallel, so it just
runs from its beginning to its end (including the parallel subtests). After
it finishes, then the cleanUp is called.

In this commit I chose a different method: I just moved the clean up into each
parallel subtest. I think this is clearer than all that parallel magic I
tried explaining in previous paragraphs.

See the section "Run a group of tests in parallel":
https://blog.golang.org/subtests

and this paragraph:
https://golang.org/pkg/testing/#hdr-Subtests_and_Sub_benchmarks
This commit is contained in:
Ondřej Budai 2020-04-30 16:05:10 +02:00
parent e2c9b9d881
commit 02b70be9c6

View file

@ -45,12 +45,6 @@ func TestFetchChecksum(t *testing.T) {
// and tries to run depsolve for each architecture. With N architectures available
// this should run cross-arch dependency solving N-1 times.
func TestCrossArchDepsolve(t *testing.T) {
// Set up temporary directory for rpm/dnf cache
dir, err := ioutil.TempDir("/tmp", "rpmmd-test-")
require.Nilf(t, err, "Failed to create tmp dir for depsolve test: %v", err)
defer os.RemoveAll(dir)
rpm := rpmmd.NewRPMMD(dir)
// Load repositories from the definition we provide in the RPM package
repoDir := "/usr/share/osbuild-composer"
@ -61,6 +55,12 @@ func TestCrossArchDepsolve(t *testing.T) {
// Run tests in parallel to speed up run times.
t.Parallel()
// Set up temporary directory for rpm/dnf cache
dir, err := ioutil.TempDir("/tmp", "rpmmd-test-")
require.Nilf(t, err, "Failed to create tmp dir for depsolve test: %v", err)
defer os.RemoveAll(dir)
rpm := rpmmd.NewRPMMD(dir)
repos, err := rpmmd.LoadRepositories([]string{repoDir}, distroStruct.Name())
require.NoErrorf(t, err, "Failed to LoadRepositories %v", distroStruct.Name())