-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
That's the races out of our test suite! #5384
base: develop
Are you sure you want to change the base?
Conversation
Also actually run the mobile driver during tests
d1bbb2a
to
7d5fb07
Compare
Oh man, so many races not detected on my local setup :( |
InMemoryPreferences will need to avoid using a goroutine here |
Good catch thanks. Fixed |
OK, some platforms are now not detecting any races, so I have enabled it on the rest and working through what I hope is the last few!!! |
Use new RunFromGoroutine API here - https://github.com/fyne-io/fyne/blob/develop/app/settings_desktop.go#L48 |
@Jacalz It seems we may need to remove or update the new pool_test. I think |
Good point, the contract includes this on
So I have removed the Set/Get test - but the Get on empty and the replacement New tests should both be OK. |
Good finds, those will all need some work because they all result in user callbacks, or widget functions, being called directly from goroutines which is against the new model |
That's it merged. Rebasing this should make it possible to click around in fyne_demo and test out any potential races. I think I got one when changing application scale in the settings menu earlier but it might have been fixed by this PR already, I don't know :) |
Thanks - fixed. I left the delay as there was a bug reported about file write delay but then it joins back to main now |
PASS!!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. This is massively impressive. Well done! I left some notes and questions in-line :)
"fyne.io/fyne/v2/theme" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestFyneApp_SetCloudProvider(t *testing.T) { | ||
a := NewWithID("io.fyne.test") | ||
a := test.NewApp() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we ought to use the new test.NewTempApp()
in all these new cases?
@@ -50,15 +50,19 @@ func (p *preferences) forceImmediateSave() { | |||
func (p *preferences) resetSavedRecently() { | |||
go func() { | |||
time.Sleep(time.Millisecond * 100) // writes are not always atomic. 10ms worked, 100 is safer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw the message earlier but this still makes me kind of worried. Are we sure that the previous reported bug about writes not being atomic just weren't a race? Are writes not atomic or are we just missing locking between this and the place where it is written?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Go, calling .Write()
on a file returns how many bytes it has written so it must be blocking until the write is complete. If this code and the write is happening on the same thread, we should not see any problem as far as I can tell.
As long as we are not reading and writing from different threads, I don't think atomic writes should matter much.
func newTestMobileApp() fyne.App { | ||
return &mobileApp{ | ||
App: fyne.CurrentApp(), | ||
driver: NewGoMobileDriver(), | ||
} | ||
} | ||
|
||
func waitAndCheck(msWait time.Duration, fn func()) { | ||
waitForCheck := make(chan struct{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not use the common pool of done channels?
s.app.propertyLock.Lock() | ||
s.app.driver.CallFromGoroutine(func() { | ||
painter.ClearFontCache() | ||
cache.ResetThemeCaches() | ||
intapp.ApplySettings(s, s.app) | ||
}) | ||
|
||
s.app.appliedTheme = s.Theme() | ||
s.app.propertyLock.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This locking around it all seems strange to me. Is it really safe? Should it not be in the scheduled function?
if isStopped { | ||
a.anim.Start() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be combined with the block above?
Working perfectly locally, let's see what CI says!
Progresses #4654
Checklist: