vatesfr / terraform-provider-xenorchestra

Xen Orchestra provider for Terraform
MIT License
150 stars 33 forks source link

Improve acceptance test suite build quality (decrease flakiness) #188

Closed ddelnano closed 9 months ago

ddelnano commented 2 years ago

The current acceptance test suite has grown since the project started. It is now comprised of 30 xenorchestra_vm resource tests, which often cause the go test command to timeout (running TIMEOUT=XXXm make testacc never succeeds on its own). This is starting to become a significant time sink on development velocity. In addition, the process listed below is time consuming and requires that I correctly identify what tests failed or were skipped:

  1. Run test suite via make testacc
  2. Identify which tests failed and which were skipped (as in go test timed out before that test was run)
  3. Run additional test commands only running the failed tests TEST='Test1|Test2|Test3|....' make testacc
  4. Repeat 2-3 until the test suite passes

There have been past efforts to improve the test suite quality:

While these have improved the test suite, it does not help with managing the test suite over time as its performance changes (test suite becomes slower, certain tests become problematic, identifying bad tests).

The goal of this issue is to allow the test suite to pass by running a single bash command. This will prevent the frequent loop identified above where commands are issued until all acceptance tests have passed.

One possible idea is to explore alternative ways of running the test suite (shell script, more proper test runner). It seems that gotestsum test runner is worth exploring. It has builtin support for re-running failed tests and can also identify what tests are slow.

ddelnano commented 1 year ago

Until this is fixed here is my solution:

$ comm -2 -3  <(git grep TestAcc | cut -d ':' -f2 | awk '{print $2}' | grep '(t' | grep -Po '.*(?=..$)' | sort) <(grep 'PASS:' ouptut.txt | awk '{print $3}' | sort ) | tr '\n' '\|'

Repeat with each successive test run.

ddelnano commented 1 year ago

I've evaluated gotestsum. Unfortunately it doesn't provide the functionality I need. It does allow re-running failed tests, but we need terraform's test sweeping to run before each additional retry (to purge VMs and other failed resources).

From reading it's source code and rakyll/go-test-trace, I believe writing a custom test runner is a good option. Essentially what it will do is keep track of all tests, run go test ... -sweep=true -json and parse the streamed output. Once the test timeout is reached it will remove the successful tests from the test list and run go test ... -sweep=true -json again with a smaller subset of tests. Separately I'd like to better understand these test failures, but I'd like to attempt this test runner first since my past attempts at understanding the tests's performance hasn't been successful.

I have a work in progress branch that I believe should be close to an initial prototype.

ddelnano commented 1 year ago

I've evaluated gotestsum. Unfortunately it doesn't provide the functionality I need. It does allow re-running failed tests, but we need terraform's test sweeping to run before each additional retry (to purge VMs and other failed resources).

I took another look at gotestsum as I was debugging my custom test runner and my initial assessment isn't quite correct. It should work with terraform's test sweeping (re-running go test after each set of failures). However when it encounters a test panic (exactly the situation I'd like to re-run in), it simply gives up.

My branch mentioned above has a github.com/ddelnano/terraform-provider-xenorchestra/testing/parallel test suite that passes with -timeout=32s, but fails with a -timeout=22s to better acceptance test whatever solution I use. Here is the behavior of gotestsum against those tests.

ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ ~/code/gotestsum/gotestsum --rerun-fails --packages="./..." -- -count=1 -timeout=22s -run="TestParallel" -v
∅  .
∅  cmd/testing (3ms)
∅  xoa/internal (11ms)
∅  xoa (12ms)
✖  cmd/testing/parallel (22.015s)

=== Failed
=== FAIL: cmd/testing/parallel TestParallelHangging (unknown)

DONE 3 tests, 1 failure in 22.558s
ERROR rerun aborted because previous run had a suspected panic and some test may not have run
ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ ~/code/gotestsum/gotestsum --rerun-fails --packages="./..." -- -count=1 -timeout=32s -run="TestParallel" -v
∅  .
∅  cmd/testing (8ms)
∅  xoa/internal (12ms)
∅  xoa (13ms)
✓  cmd/testing/parallel (30.022s)

DONE 3 tests in 30.561s

So it seems gotestsum may be able to be extended to not error in this situation, but I need to better understand what is more feasible.

ddelnano commented 1 year ago

I've also created a post on the Hashicorp discuss forums. I'm hoping to receive more guidance from other provider developers / Hashicorp on other things I haven't considered.

ddelnano commented 1 year ago

While gotestsum does not handle go test timeouts that result in panics, I've determined that I can extend it easily to support the behavior I need (https://github.com/gotestyourself/gotestsum/commit/8c70ff05e83bc93e5e042151a4d25343f1dfe4f8). My sample test package that panics if a timeout occurs within 30 seconds proves that my patch works as seen below.

gotestsum output for sample panic test suite ``` ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ TF_ACC=1 ~/code/gotestsum/gotestsum --rerun-fails=2 --packages='github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel' -- -v -count=1 -timeout=11s ✖ cmd/testing/parallel (11.006s) DONE 3 tests, 2 failures in 11.242s ✓ cmd/testing/parallel (10.01s) ✓ cmd/testing/parallel (10.005s) === Failed === FAIL: cmd/testing/parallel TestParallelSlightHangging (unknown) === FAIL: cmd/testing/parallel TestParallelHangging (unknown) DONE 2 runs, 5 tests, 2 failures in 31.721s ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ echo $? 0 ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ TF_ACC=1 ~/code/gotestsum/gotestsum --rerun-fails=2 --packages='github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel' -- -v -count=1 -timeout=9s ✖ cmd/testing/parallel (9.012s) DONE 3 tests, 3 failures in 9.238s ✖ cmd/testing/parallel (9.013s) ✖ cmd/testing/parallel (9.011s) ✖ cmd/testing/parallel (9.005s) DONE 2 runs, 6 tests, 6 failures in 36.966s ✖ cmd/testing/parallel (9.012s) ✖ cmd/testing/parallel (9.009s) ✖ cmd/testing/parallel (9.007s) === Failed === FAIL: cmd/testing/parallel TestParallelSuccessful (unknown) === FAIL: cmd/testing/parallel TestParallelHangging (unknown) panic: test timed out after 9s goroutine 17 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc000007860, 0xc000070c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc000000140?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x527fda?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc000000140) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x1007f180a3e3338?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 6 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 7 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSuccessful(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:30 +0x27 testing.tRunner(0xc000007a00, 0x531060) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f goroutine 8 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:35 +0x27 testing.tRunner(0xc000007d40, 0x531050) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f goroutine 9 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSlightHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:40 +0x27 testing.tRunner(0xc0001161a0, 0x531058) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelSlightHangging (unknown) === FAIL: cmd/testing/parallel TestParallelSuccessful (re-run 1) (unknown) panic: test timed out after 9s goroutine 17 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc000007860, 0xc000053c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc000000140?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x527fda?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc000000140) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x1007fb420eea338?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 6 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 7 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSuccessful(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:30 +0x27 testing.tRunner(0xc000007a00, 0x531060) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelHangging (re-run 1) (unknown) panic: test timed out after 9s goroutine 17 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc000007860, 0xc000053c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc000000140?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x527fda?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc000000140) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x1007f87ec7b6338?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 6 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 7 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:35 +0x27 testing.tRunner(0xc000007a00, 0x531050) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelSlightHangging (re-run 1) (unknown) panic: test timed out after 9s goroutine 20 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc0000829c0, 0xc000093c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc0000c20a0?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x7fd37832dfff?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc0000c20a0) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x7fd39f45f5b8?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 18 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 19 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSlightHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:40 +0x27 testing.tRunner(0xc000082b60, 0x531058) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelSuccessful (re-run 2) (unknown) panic: test timed out after 9s goroutine 20 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc00011a680, 0xc00008dc78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc0001300a0?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x7f3262c6efff?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc0001300a0) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x7f3289da0a68?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 18 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 19 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSuccessful(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:30 +0x27 testing.tRunner(0xc00011a820, 0x531060) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelHangging (re-run 2) (unknown) panic: test timed out after 9s goroutine 33 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc0000829c0, 0xc000093c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc0000c20a0?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x7f72d54e6fff?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc0000c20a0) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x7f72fc6185b8?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 18 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 19 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:35 +0x27 testing.tRunner(0xc000082b60, 0x531050) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f === FAIL: cmd/testing/parallel TestParallelSlightHangging (re-run 2) (unknown) panic: test timed out after 9s goroutine 17 [running]: testing.(*M).startAlarm.func1() /usr/lib/go/src/testing/testing.go:2036 +0x8e created by time.goFunc /usr/lib/go/src/time/sleep.go:176 +0x32 goroutine 1 [chan receive]: testing.tRunner.func1() /usr/lib/go/src/testing/testing.go:1412 +0x4a5 testing.tRunner(0xc000007860, 0xc000053c78) /usr/lib/go/src/testing/testing.go:1452 +0x144 testing.runTests(0xc000000140?, {0x605400, 0x3, 0x3}, {0x4a6be9?, 0x527fda?, 0x609ca0?}) /usr/lib/go/src/testing/testing.go:1844 +0x456 testing.(*M).Run(0xc000000140) /usr/lib/go/src/testing/testing.go:1726 +0x5d9 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain(0x1007f98700c5338?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:21 +0x5e main.main() _testmain.go:53 +0x1d3 goroutine 6 [sleep]: time.Sleep(0x2540be400) /usr/lib/go/src/runtime/time.go:195 +0x135 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain.func1() /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:16 +0x2c created by github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestMain /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:14 +0x54 goroutine 7 [chan receive]: github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.waitForChannel(...) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:25 github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel.TestParallelSlightHangging(0x0?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/cmd/testing/parallel/main_test.go:40 +0x27 testing.tRunner(0xc000007a00, 0x531058) /usr/lib/go/src/testing/testing.go:1446 +0x10b created by testing.(*T).Run /usr/lib/go/src/testing/testing.go:1493 +0x35f DONE 3 runs, 9 tests, 9 failures in 64.690s ```

I will attempt to upstream this behavior, but for now I believe that gotestsum is the correct approach to easily run the test suite.

I have to modify how the terraform test setup code works, so the solution isn't finished yet. However, I'm confident that it will be workable to solve this problem at this point. My previous work to write my own test runner ran into issues and I think it's better to build on top of an existing project than piece together a minimal one off test runner.

As an extension of this issue, I'd like to setup continuous integration so PRs are able to be tested automatically. Once I have this issue resolved, I will be looking into the CI job further.

ddelnano commented 1 year ago

I have confirmed that the changes in #217 result in a build that succeeds even when a subset of tests hit the timeout and panic. This significantly reduces the manual work to run the test suite and will drastically improve development and release time.

gotestsum output for acceptance test suite ``` $ TF_ACC=1 ~/code/gotestsum/gotestsum --rerun-fails=4 --rerun-fails-max-failures=1000 --packages='./...' -- ./... -v -count=1 -timeout=25m -sweep=true [ ... ] goroutine 47250 [select]: google.golang.org/grpc/internal/transport.(*recvBufferReader).read(0xc00198cb90, {0xc001162250, 0x5, 0x5}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/transport.go:177 +0x90 google.golang.org/grpc/internal/transport.(*recvBufferReader).Read(0xc00198cb90, {0xc001162250?, 0xc00271e978?, 0xc002727730?}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/transport.go:171 +0x178 google.golang.org/grpc/internal/transport.(*transportReader).Read(0xc000afbce0, {0xc001162250?, 0xc0027277a8?, 0xa45067?}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/transport.go:482 +0x32 io.ReadAtLeast({0x10807e0, 0xc000afbce0}, {0xc001162250, 0x5, 0x5}, 0x5) /usr/lib/go/src/io/io.go:332 +0x9a io.ReadFull(...) /usr/lib/go/src/io/io.go:351 google.golang.org/grpc/internal/transport.(*Stream).Read(0xc0024de900, {0xc001162250, 0x5, 0x5}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/transport.go:466 +0xa5 google.golang.org/grpc.(*parser).recvMsg(0xc001162240, 0x400000) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/rpc_util.go:503 +0x47 google.golang.org/grpc.recvAndDecompress(0xc000afb620?, 0xc0024de900, {0x0, 0x0}, 0x400000, 0x0, {0x0, 0x0}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/rpc_util.go:634 +0x66 google.golang.org/grpc.recv(0x8?, {0x7f544d3aab80, 0x1674798}, 0x203000?, {0x0?, 0x0?}, {0xe70440, 0xc00198cbe0}, 0xc002727a30?, 0x0, ...) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/rpc_util.go:702 +0x6e google.golang.org/grpc.(*serverStream).RecvMsg(0xc00240c600, {0xe70440?, 0xc00198cbe0}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/stream.go:1496 +0x178 github.com/hashicorp/go-plugin/internal/plugin.(*gRPCBrokerStartStreamServer).Recv(0xc003a89a20) /home/ddelnano/go/pkg/mod/github.com/hashicorp/go-plugin@v1.4.0/internal/plugin/grpc_broker.pb.go:167 +0x4c github.com/hashicorp/go-plugin.(*gRPCBrokerServer).StartStream(0xc000e57ad0, {0x108b220, 0xc003a89a20}) /home/ddelnano/go/pkg/mod/github.com/hashicorp/go-plugin@v1.4.0/grpc_broker.go:84 +0x152 github.com/hashicorp/go-plugin/internal/plugin._GRPCBroker_StartStream_Handler({0xde9d60?, 0xc000e57ad0}, {0x10897f0?, 0xc00240c600}) /home/ddelnano/go/pkg/mod/github.com/hashicorp/go-plugin@v1.4.0/internal/plugin/grpc_broker.pb.go:148 +0x9f google.golang.org/grpc.(*Server).processStreamingRPC(0xc003a32000, {0x108b880, 0xc002016480}, 0xc0024de900, 0xc000e57b60, 0x162a7c0, 0x0) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:1441 +0xd4a google.golang.org/grpc.(*Server).handleStream(0xc003a32000, {0x108b880, 0xc002016480}, 0xc0024de900, 0x0) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:1521 +0x9ea google.golang.org/grpc.(*Server).serveStreams.func1.2() /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:859 +0x98 created by google.golang.org/grpc.(*Server).serveStreams.func1 /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:857 +0x28a goroutine 47251 [select]: github.com/hashicorp/go-plugin.(*gRPCBrokerServer).StartStream.func1() /home/ddelnano/go/pkg/mod/github.com/hashicorp/go-plugin@v1.4.0/grpc_broker.go:70 +0x105 created by github.com/hashicorp/go-plugin.(*gRPCBrokerServer).StartStream /home/ddelnano/go/pkg/mod/github.com/hashicorp/go-plugin@v1.4.0/grpc_broker.go:68 +0x131 goroutine 47264 [select]: github.com/hashicorp/terraform-plugin-go/tfprotov5/server.mergeStop({0x1087608?, 0xc0012e7b00?}, 0xc0035f63e0, 0xc0038674a0) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-go@v0.2.1/tfprotov5/server/server.go:111 +0x74 created by github.com/hashicorp/terraform-plugin-go/tfprotov5/server.(*server).stoppableContext /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-go@v0.2.1/tfprotov5/server/server.go:129 +0x158 goroutine 47258 [select]: google.golang.org/grpc/internal/transport.(*controlBuffer).get(0xc0012d9040, 0x1) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/controlbuf.go:395 +0x115 google.golang.org/grpc/internal/transport.(*loopyWriter).run(0xc001859aa0) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/controlbuf.go:515 +0x85 google.golang.org/grpc/internal/transport.newHTTP2Server.func2() /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/http2_server.go:291 +0xce created by google.golang.org/grpc/internal/transport.newHTTP2Server /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/http2_server.go:288 +0x14d3 goroutine 47259 [select]: google.golang.org/grpc/internal/transport.(*http2Server).keepalive(0xc0044ba900) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/http2_server.go:979 +0x233 created by google.golang.org/grpc/internal/transport.newHTTP2Server /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/http2_server.go:299 +0x1518 goroutine 47260 [IO wait]: internal/poll.runtime_pollWait(0x7f542e6edb50, 0x72) /usr/lib/go/src/runtime/netpoll.go:305 +0x89 internal/poll.(*pollDesc).wait(0xc0011e5280?, 0xc0044c8000?, 0x0) /usr/lib/go/src/internal/poll/fd_poll_runtime.go:84 +0x32 internal/poll.(*pollDesc).waitRead(...) /usr/lib/go/src/internal/poll/fd_poll_runtime.go:89 internal/poll.(*FD).Read(0xc0011e5280, {0xc0044c8000, 0x8000, 0x8000}) /usr/lib/go/src/internal/poll/fd_unix.go:167 +0x25a net.(*netFD).Read(0xc0011e5280, {0xc0044c8000?, 0x0?, 0xc002ed64e0?}) /usr/lib/go/src/net/fd_posix.go:55 +0x29 net.(*conn).Read(0xc0001259f8, {0xc0044c8000?, 0x0?, 0xc002728cd0?}) /usr/lib/go/src/net/net.go:183 +0x45 bufio.(*Reader).Read(0xc001859a40, {0xc0000f2818, 0x9, 0x0?}) /usr/lib/go/src/bufio/bufio.go:237 +0x1bb io.ReadAtLeast({0x107e200, 0xc001859a40}, {0xc0000f2818, 0x9, 0x9}, 0x9) /usr/lib/go/src/io/io.go:332 +0x9a io.ReadFull(...) /usr/lib/go/src/io/io.go:351 golang.org/x/net/http2.readFrameHeader({0xc0000f2818?, 0x9?, 0xc00310d260?}, {0x107e200?, 0xc001859a40?}) /home/ddelnano/go/pkg/mod/golang.org/x/net@v0.0.0-20200707034311-ab3426394381/http2/frame.go:237 +0x6e golang.org/x/net/http2.(*Framer).ReadFrame(0xc0000f27e0) /home/ddelnano/go/pkg/mod/golang.org/x/net@v0.0.0-20200707034311-ab3426394381/http2/frame.go:492 +0x95 google.golang.org/grpc/internal/transport.(*http2Server).HandleStreams(0xc0044ba900, 0x6430376330362d63?, 0x2c22393730653064?) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/internal/transport/http2_server.go:459 +0x177 google.golang.org/grpc.(*Server).serveStreams(0xc003a32000, {0x108b880?, 0xc0044ba900}) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:843 +0x142 google.golang.org/grpc.(*Server).handleRawConn.func1() /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:802 +0x34 created by google.golang.org/grpc.(*Server).handleRawConn /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:801 +0x3fd goroutine 47263 [select]: github.com/sourcegraph/jsonrpc2.Waiter.Wait({0x0?}, {0x1087640, 0xc00003c170}, {0xd3d0c0, 0xc000644060}) /home/ddelnano/go/pkg/mod/github.com/sourcegraph/jsonrpc2@v0.0.0-20210201082850-366fbb520750/jsonrpc2.go:461 +0x99 github.com/sourcegraph/jsonrpc2.(*Conn).Call(0x8?, {0x1087640, 0xc00003c170}, {0xed22b0?, 0x0?}, {0xdad060?, 0xc002ebf170?}, {0xd3d0c0, 0xc000644060}, {0x0, ...}) /home/ddelnano/go/pkg/mod/github.com/sourcegraph/jsonrpc2@v0.0.0-20210201082850-366fbb520750/jsonrpc2.go:423 +0xac github.com/ddelnano/terraform-provider-xenorchestra/client.NewClient({{0xc0000460c8, 0x16}, {0xc00003c159, 0x5}, {0xc0000401bd, 0x8}, 0x0}) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/client/client.go:178 +0x36e github.com/ddelnano/terraform-provider-xenorchestra/xoa.xoaConfigure(0xebc91c?) /home/ddelnano/go/src/github.com/ddelnano/terraform-provider-xenorchestra/xoa/provider.go:72 +0x1aa github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Provider).Configure(0xc0005e20f0, {0x10876b0, 0xc001b3c570}, 0xc0035f65c0?) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/v2@v2.4.3/helper/schema/provider.go:279 +0x12f github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ConfigureProvider(0xc0033f5098, {0x1087608, 0xc0012e7b00}, 0xc001163218) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/v2@v2.4.3/helper/schema/grpc_provider.go:523 +0x27b github.com/hashicorp/terraform-plugin-go/tfprotov5/server.(*server).Configure(0xc00498fbc0, {0x10876b0?, 0xc001b3c150?}, 0xc0012e7ac0) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-go@v0.2.1/tfprotov5/server/server.go:182 +0x147 github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_Configure_Handler({0xe7fca0?, 0xc00498fbc0}, {0x10876b0, 0xc001b3c150}, 0xc00403c420, 0x0) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-go@v0.2.1/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:326 +0x170 google.golang.org/grpc.(*Server).processUnaryRPC(0xc003a32000, {0x108b880, 0xc0044ba900}, 0xc0024dee00, 0xc000e57e60, 0x1634518, 0x0) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:1194 +0xcab google.golang.org/grpc.(*Server).handleStream(0xc003a32000, {0x108b880, 0xc0044ba900}, 0xc0024dee00, 0x0) /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:1517 +0xa2f google.golang.org/grpc.(*Server).serveStreams.func1.2() /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:859 +0x98 created by google.golang.org/grpc.(*Server).serveStreams.func1 /home/ddelnano/go/pkg/mod/google.golang.org/grpc@v1.32.0/server.go:857 +0x28a goroutine 47265 [select]: github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.mergeStop({0x1087608?, 0xc0012e7cc0?}, 0xc0035f65b0, 0xc003caf8c0) /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/v2@v2.4.3/helper/schema/grpc_provider.go:44 +0x74 created by github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).StopContext /home/ddelnano/go/pkg/mod/github.com/hashicorp/terraform-plugin-sdk/v2@v2.4.3/helper/schema/grpc_provider.go:60 +0x158 === FAIL: xoa TestAccXONetworkDataSource_read (re-run 1) (3.07s) data_source_xenorchestra_network_test.go:43: Step 1/1 error: Error running pre-apply refresh: exit status 1 Error: Your query returned more than one result: [{Id:cb292945-e8d4-361b-b0b4-0729f98aeb8e NameLabel:terraform-acc-network-1 Bridge:xapi109 PoolId:355ee47d-ff4c-4924-3db2-fd86ae629676} {Id:661a1a2b-368a-9390-6e0b-62a5291cdbd2 NameLabel:terraform-acc-network-1 Bridge:xapi115 PoolId:355ee47d-ff4c-4924-3db2-fd86ae629676} {Id:0432d2a7-f268-6999-eb43-c6a2345b2133 NameLabel:terraform-acc-network-1 Bridge:xapi118 PoolId:355ee47d-ff4c-4924-3db2-fd86ae629676} {Id:a59e89ed-65c2-346b-c309-54a02f13eb6d NameLabel:terraform-acc-network-1 Bridge:xapi112 PoolId:355ee47d-ff4c-4924-3db2-fd86ae629676}]. Use `pool_id` or other fields to filter the result down to a single network === FAIL: xoa TestAccXenorchestraVm_createWithMutipleDisks (re-run 1) (51.34s) resource_xenorchestra_vm_test.go:945: Step 1/1 error: After applying this test step, the plan was not empty. stdout: An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # xenorchestra_vm.bar will be updated in-place ~ resource "xenorchestra_vm" "bar" { auto_poweron = false cloud_config = "template" core_os = false cpu_cap = 0 cpu_weight = 0 cpus = 1 exp_nested_hvm = false hvm_boot_firmware = "bios" id = "52f2f9a5-174c-aec2-1fdf-17ca835bbb01" ipv4_addresses = [] ipv6_addresses = [] memory_max = 4295000000 name_description = "description" name_label = "terraform-acc - TestAccXenorchestraVm_createWithMutipleDisks" power_state = "Running" start_delay = 0 template = "9b0fd2ac-c89a-93b4-5103-8506391395cd" vga = "std" videoram = 8 wait_for_ip = false ~ disk { attached = true name_label = "disk 1" position = "0" ~ size = 4294967296 -> 10001317888 sr_id = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3" vbd_id = "41c4cead-bce1-7eb9-f0a8-7f6aafbfed47" vdi_id = "295dc4eb-96d0-4c45-8657-77e387796d9c" } disk { attached = true name_label = "disk 2" position = "1" size = 10001317888 sr_id = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3" vbd_id = "c07b1553-c1a6-5c1f-39b5-4487c6d2125b" vdi_id = "0a8cd9a9-7c2b-4aee-884c-1bf891474122" } network { attached = true device = "0" ipv4_addresses = [] ipv6_addresses = [] mac_address = "e6:08:98:9b:45:6e" network_id = "6c4e1cdc-9fe0-0603-e53d-4790d1fce8dd" } } Plan: 0 to add, 1 to change, 0 to destroy. DONE 3 runs, 96 tests, 1 skipped, 10 failures in 2798.600s # Verify the build succeeded ddelnano@ddelnano-desktop:~/go/src/github.com/ddelnano/terraform-provider-xenorchestra$ echo $? 0 ```
ddelnano commented 9 months ago

This is no longer an issue as there is build infrastructure within the Vates lab now.