Skip to content

Conversation

j0sh
Copy link
Collaborator

@j0sh j0sh commented Sep 16, 2025

The new synctest package, introduced in golang 1.25, makes tests involving time and concurrency much faster and more reliable. All the discovery tests that took more than 100ms on my machine were converted to use synctest.

This surfaced a number of race conditions in both the tests and the code itself so these were also fixed.

Timings with go test -timeout 10s -count 1 -race

Before:
ok github.com/livepeer/go-livepeer/discovery 7.087s

After:
ok github.com/livepeer/go-livepeer/discovery 0.817s

Since syncest depends on a nested call similar to a sub-test, I opted to just rename the top level test function in the interests of not having to re-indent the entire file, or having yet another level of indentation around the file.

@j0sh j0sh requested review from victorges, leszko and mjh1 September 16, 2025 06:10
@github-actions github-actions bot added dependencies Pull requests that update a dependency file go Pull requests that update Go code labels Sep 16, 2025
Base automatically changed from ja/multiple-serviceuri to master September 17, 2025 15:30
@j0sh j0sh force-pushed the ja/discovery-synctest branch from a1ec486 to d8f25d8 Compare September 17, 2025 16:22
@j0sh
Copy link
Collaborator Author

j0sh commented Sep 17, 2025

Rebased onto latest master to fix merge conflicts, no other changes

Copy link
Contributor

@mjh1 mjh1 left a comment

Choose a reason for hiding this comment

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

nice 👍

assert.Nil(err, "Should not be error")
assert.Len(infos, 1, "Should return one orchestrator")
assert.Equal("transcoderfromtestserver", infos[0].RemoteInfo.Transcoder)
wgWait(&wg)
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to check the returned bool?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good idea, checked in a6110ec

first := true
serverGetOrchInfo = func(ctx context.Context, bcast common.Broadcaster, orchestratorServer *url.URL, params server.GetOrchestratorInfoParams) (*net.OrchestratorInfo, error) {
mu.Lock()
if first {
Copy link
Contributor

Choose a reason for hiding this comment

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

why were we pausing on the first request, don't really understand that

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

me neither - best guess is some early test needed it or had a race condition (probably the deadlock one), and it got copied everywhere else.

I double checked the rest of these tests and seems that I mistakenly removed the sleep from the deadlock test; that apparently was meant to drop one of the orchs so it wouldn't pass discovery. Re-added it, hopefully with a little better explanation in a6110ec (I still have no idea how this could have caused a deadlock though.)

Copy link
Member

@victorges victorges left a comment

Choose a reason for hiding this comment

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

this synctest is really neat!

The golang 1.25 update turned out into something of an ordeal, so
splitting it up from #3739
to allow for better review.

While everything compiled in 1.25, some tests and CI steps broke.

* Go lint needed to be updated to v2+ to support golang 1.25
* Bumping go vet from v1 to v2 entailed a bunch of CLI changes.
  Tried to make those 1-to-1 as much as possible, however:

  Go fmt now needs to be invoked separately for golint. We check
  go fmt in the CI step right before lint ... so just remove the
  go fmt step?

  The revive linter flagged a ton of missing comments. But it
  seems the linter only applies to the `pm` and `verification`
  packages which hardly change. Rather than update those packages,
  remove the use of the `revive` linter.

* Some linting step (not sure which one? vet?) now complains
  about format string functions being used incorrectly, eg
  using a variable in place of a format string literal.
  Those were fixed in the code.

* The `rand.Seed` function apparently became a no-op as of
  golang 1.24 and that broke most of our tests that use the RNG.
  Removed the init() function that sets the seed, and added a
  package level RNG context (using the same seed as the old init)
  and updated any failing tests to use that context.

  Not all uses of the RNG were updated, just ones that broke tests.
  The global RNG is safely initialized so we can continue to use it
  by default in the code that still uses it without test coverage.
@j0sh j0sh force-pushed the ja/discovery-synctest branch from f3310ea to 424ddbc Compare September 22, 2025 23:01
@j0sh j0sh changed the title ai/live: Update to golang 1.25, use synctest in discovery ai/live: Use synctest in discovery Sep 22, 2025
@j0sh j0sh changed the base branch from master to ja/golang-1.25 September 22, 2025 23:02
The new synctest package, introduced in golang 1.25, makes tests
much faster and more reliable. All the discovery tests that took
more than 100ms on my machine were converted to use synctest.

This surfaced a number of race conditions in both the tests and
the code itself so these were also fixed.

Timings with `go test -timeout 10s -count 1 -race`

Before:
ok      github.com/livepeer/go-livepeer/discovery       7.087s

After:
ok      github.com/livepeer/go-livepeer/discovery       0.817s

Since syncest depends on a nested call similar to a sub-test, I
opted to just rename the top level test function in the interests
of not having to re-indent the entire file, or having yet another
level of indentation around the file.
@j0sh j0sh force-pushed the ja/discovery-synctest branch from 424ddbc to b6015f2 Compare September 22, 2025 23:04
@j0sh
Copy link
Collaborator Author

j0sh commented Sep 22, 2025

Since the update for golang 1.25 became more involved than I was expecting, separated that out in its own PR in #3745 so this one has just the synctest changes. Once that goes in, this one will go in too.

Base automatically changed from ja/golang-1.25 to master September 25, 2025 20:30
j0sh added a commit that referenced this pull request Sep 25, 2025
The golang 1.25 update turned out into something of an ordeal, so
splitting it up from #3739
to allow for better review.

While everything compiled in 1.25, some tests and CI steps broke.

* Go lint needed to be updated to v2+ to support golang 1.25
* Bumping go vet from v1 to v2 entailed a bunch of CLI changes.
  Tried to make those 1-to-1 as much as possible, however:

  Go fmt now needs to be invoked separately for golint. We check
  go fmt in the CI step right before lint ... so just remove the
  go fmt step?

  The revive linter flagged a ton of missing comments. But it
  seems the linter only applies to the `pm` and `verification`
  packages which hardly change. Rather than update those packages,
  remove the use of the `revive` linter.

* Some linting step (not sure which one? vet?) now complains
  about format string functions being used incorrectly, eg
  using a variable in place of a format string literal.
  Those were fixed in the code.

* The `rand.Seed` function apparently became a no-op as of
  golang 1.24 and that broke most of our tests that use the RNG.
  Removed the init() function that sets the seed, and added a
  package level RNG context (using the same seed as the old init)
  and updated any failing tests to use that context.

  Not all uses of the RNG were updated, just ones that broke tests.
  The global RNG is safely initialized so we can continue to use it
  by default in the code that still uses it without test coverage.

* Fix race condition in discovery uncovered by golang 1.25
Copy link

codecov bot commented Sep 25, 2025

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 31.14775%. Comparing base (afef0a6) to head (4099731).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
common/testutil.go 0.00000% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                 Coverage Diff                 @@
##              master       #3739         +/-   ##
===================================================
- Coverage   31.14906%   31.14775%   -0.00131%     
===================================================
  Files            158         158                 
  Lines          47552       47554          +2     
===================================================
  Hits           14812       14812                 
- Misses         31852       31854          +2     
  Partials         888         888                 
Files with missing lines Coverage Δ
common/testutil.go 16.12903% <0.00000%> (-0.53764%) ⬇️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update afef0a6...4099731. Read the comment docs.

Files with missing lines Coverage Δ
common/testutil.go 16.12903% <0.00000%> (-0.53764%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@j0sh j0sh merged commit 7f04401 into master Sep 26, 2025
28 of 30 checks passed
@j0sh j0sh deleted the ja/discovery-synctest branch September 26, 2025 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file go Pull requests that update Go code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants