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

Data race in bubbletea.NewProgram.WithColorCache.func1() #910

Open
3v1n0 opened this issue Jan 23, 2024 · 4 comments
Open

Data race in bubbletea.NewProgram.WithColorCache.func1() #910

3v1n0 opened this issue Jan 23, 2024 · 4 comments

Comments

@3v1n0
Copy link

3v1n0 commented Jan 23, 2024

Describe the bug
Data race when runnig test code with -race

Trace

WARNING: DATA RACE
Write at 0x00c00013358a by goroutine 342:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /tmp/go-path/pkg/mod/github.com/muesli/termenv@v0.15.2/output.go:107 +0x37
  github.com/charmbracelet/bubbletea.NewProgram()
      /tmp/go-path/pkg/mod/github.com/charmbracelet/bubbletea@v0.25.0/tea.go:209 +0x353
  github.com/ubuntu/authd/pam/internal/adapter.TestGdmModel.func23()
      /home/marco/Dev/authd/pam/internal/adapter/gdmmodel_test.go:1279 +0xb44
  testing.tRunner()
      /snap/go/10489/src/testing/testing.go:1595 +0x261
  testing.(*T).Run.func1()
      /snap/go/10489/src/testing/testing.go:1648 +0x44

Previous read at 0x00c000133588 by goroutine 334:
  github.com/charmbracelet/bubbletea.(*Program).checkResize()
      /tmp/go-path/pkg/mod/github.com/charmbracelet/bubbletea@v0.25.0/tty.go:99 +0x67
  github.com/charmbracelet/bubbletea.(*Program).handleResize.func1()
      /tmp/go-path/pkg/mod/github.com/charmbracelet/bubbletea@v0.25.0/tea.go:259 +0x33

Goroutine 342 (running) created at:
  testing.(*T).Run()
      /snap/go/10489/src/testing/testing.go:1648 +0x845
  github.com/ubuntu/authd/pam/internal/adapter.TestGdmModel()
      /home/marco/Dev/authd/pam/internal/adapter/gdmmodel_test.go:1235 +0x5c08
  testing.tRunner()
      /snap/go/10489/src/testing/testing.go:1595 +0x261
  testing.(*T).Run.func1()
      /snap/go/10489/src/testing/testing.go:1648 +0x44

Code here isn't doing anything just calling into bubbletea code, this can be workarounded by using tea.WithOutput(os.Stdout) so that termenv.WithColorCache is not called.

@ReneWerner87
Copy link

Same for me

can someone take a look at this
@muesli @meowgorithm @caarlos0

Click here for the race condition log
WARNING: DATA RACE
Write at 0x00c00013214a by goroutine 13:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_View()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:84 +0x64
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Previous write at 0x00c00013214a by goroutine 11:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Initialize()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:52 +0x64
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Goroutine 13 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294

Goroutine 11 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294
==================
==================
WARNING: DATA RACE
Write at 0x00c00013214a by goroutine 12:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Update()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:63 +0x68
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Previous read at 0x00c000132148 by goroutine 11:
--- FAIL: Test_Prompt_ParseBool (0.00s)
    testing.go:1398: race detected during execution of test
  github.com/muesli/termenv.(*Output).isTTY()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/termenv.go:38 +0x114
  github.com/muesli/termenv.(*Output).BackgroundColor.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:158 +0x30
  sync.(*Once).doSlow()
      /opt/homebrew/opt/go/libexec/src/sync/once.go:74 +0xb4
  sync.(*Once).Do()
      /opt/homebrew/opt/go/libexec/src/sync/once.go:65 +0x40
  github.com/muesli/termenv.(*Output).BackgroundColor()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:166 +0x78
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:111 +0x50
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Initialize()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:52 +0x64
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Goroutine 12 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294

Goroutine 11 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294
==================
==================
WARNING: DATA RACE
Read at 0x00c00013214a by goroutine 12:
  github.com/muesli/termenv.(*Output).ForegroundColor()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:146 +0x54
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:110 +0x48
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Update()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:63 +0x68
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Previous write at 0x00c00013214a by goroutine 9:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_YesOrNo()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:35 +0x40
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Goroutine 12 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294

Goroutine 9 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294
==================
==================
WARNING: DATA RACE
Write at 0x00c00013214a by goroutine 8:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Answer()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:27 +0x40
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Previous read at 0x00c00013214a by goroutine 13:
  github.com/muesli/termenv.(*Output).ForegroundColor()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:146 +0x54
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:110 +0x48
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_View()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:84 +0x64
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Goroutine 8 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294

Goroutine 13 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294
==================
==================
WARNING: DATA RACE
Read at 0x00c00013214a by goroutine 12:
  github.com/muesli/termenv.(*Output).BackgroundColor()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:165 +0x54
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:111 +0x50
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_Update()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:63 +0x68
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Previous write at 0x00c00013214a by goroutine 7:
  github.com/charmbracelet/bubbletea.NewProgram.WithColorCache.func1()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/muesli/termenv/output.go:107 +0x38
  github.com/charmbracelet/bubbletea.NewProgram()
      /Users/wernerr/projects/fiberProjects/cli/vendor/github.com/charmbracelet/bubbletea/tea.go:209 +0x304
  github.com/gofiber/cli/cmd/internal.NewPrompt()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt.go:30 +0x1dc
  github.com/gofiber/cli/cmd/internal.Test_Prompt_New()
      /Users/wernerr/projects/fiberProjects/cli/cmd/internal/prompt_test.go:16 +0x88
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.(*T).Run.gowrap1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x40

Goroutine 12 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294

Goroutine 7 (running) created at:
  testing.(*T).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1742 +0x5e4
  testing.runTests.func1()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2161 +0x80
  testing.tRunner()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:1689 +0x180
  testing.runTests()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2159 +0x6e0
  testing.(*M).Run()
      /opt/homebrew/opt/go/libexec/src/testing/testing.go:2027 +0xb74
  main.main()
      _testmain.go:59 +0x294
==================

we wanted to use the pack for our fiber cli:
https://github.com/gofiber/cli

to support our project with a cli
https://github.com/gofiber/fiber
image

reproducible with test command:

go test ./... -race

would also say that you should activate race detection when running your

run: go test -v ./...

thank you, great work on the project

@hmcalister
Copy link

It looks like this race condition is being caused by the Output.cache variable in github.com/muesli/termenv/output.go. Specifically, from the logs it seems as if the problematic write is at line 107 and read is at line 146. I think (if I understand this correctly) that the issue arises from termenv rather than bubbletea?

@caarlos0
Copy link
Member

caarlos0 commented May 3, 2024

can you share a reproducible? I can then take a look...

thanks!

@caarlos0
Copy link
Member

caarlos0 commented May 3, 2024

FWIW, I believe that in tests, you'll need to set a different output/input for each test.

Also might worth a look: https://github.com/charmbracelet/x/tree/main/exp/teatest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants