Data race in bubbletea.NewProgram.WithColorCache.func1()
3v1n0 opened this issue · 4 comments
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.
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
reproducible with test command:
go test ./... -race
would also say that you should activate race detection when running your
bubbletea/.github/workflows/build.yml
Line 36 in 1c6e74d
thank you, great work on the project
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?
can you share a reproducible? I can then take a look...
thanks!
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