test(adapters): wait for focus and skip truncated reads in timing-sensitive tests (#8)
- commit
- 75c48282798e9b2c48a5e28f00e17cd71ce8074e
- author
- bnema · · 2026-09-27 05:59 UTC
- committer
- GitHub · · 2026-09-27 05:59 UTC
- parent
- 368d496
- signature
- GPG Unverified
B5690EEEBB952194The key is unknown
2 files · +14 -12
M internal/adapters/config/watch_test.go +12 -6
| @@ -50,15 +50,21 @@ func TestWatch(t *testing.T) { | |||
| 50 | 50 | } | |
| 51 | 51 | } | |
| 52 | 52 | write(path, "background = #000000\n") | |
| 53 | + | // receive waits for want. A slow machine may pause longer than the | |
| 54 | + | // debounce between WriteFile's truncation and its write: the | |
| 55 | + | // watcher then reads an empty file first, which is skipped here. | |
| 53 | 56 | receive := func(want string) { | |
| 54 | 57 | t.Helper() | |
| 55 | - | select { | |
| 56 | - | case c := <-out: | |
| 57 | - | if c.Config.Background.Color != want { | |
| 58 | - | t.Fatalf("color %s, want %s", c.Config.Background.Color, want) | |
| 58 | + | deadline := time.After(time.Second) | |
| 59 | + | for { | |
| 60 | + | select { | |
| 61 | + | case c := <-out: | |
| 62 | + | if c.Config.Background.Color == want { | |
| 63 | + | return | |
| 64 | + | } | |
| 65 | + | case <-deadline: | |
| 66 | + | t.Fatalf("no config change to %s", want) | |
| 59 | 67 | } | |
| 60 | - | case <-time.After(time.Second): | |
| 61 | - | t.Fatal("no config change") | |
| 62 | 68 | } | |
| 63 | 69 | } | |
| 64 | 70 | receive("#000000") | |
| @@ -50,15 +50,21 @@ func TestWatch(t *testing.T) { | |||||
| 50 | } | 50 | } | ||
| 51 | } | 51 | } | ||
| 52 | write(path, "background = #000000\n") | 52 | write(path, "background = #000000\n") | ||
| 53 | + | // receive waits for want. A slow machine may pause longer than the | |||
| 54 | + | // debounce between WriteFile's truncation and its write: the | |||
| 55 | + | // watcher then reads an empty file first, which is skipped here. | |||
| 53 | receive := func(want string) { | 56 | receive := func(want string) { | ||
| 54 | t.Helper() | 57 | t.Helper() | ||
| 55 | - | select { | 58 | + | deadline := time.After(time.Second) |
| 56 | - | case c := <-out: | 59 | + | for { |
| 57 | - | if c.Config.Background.Color != want { | 60 | + | select { |
| 58 | - | t.Fatalf("color %s, want %s", c.Config.Background.Color, want) | 61 | + | case c := <-out: |
| 62 | + | if c.Config.Background.Color == want { | |||
| 63 | + | return | |||
| 64 | + | } | |||
| 65 | + | case <-deadline: | |||
| 66 | + | t.Fatalf("no config change to %s", want) | |||
| 59 | } | 67 | } | ||
| 60 | - | case <-time.After(time.Second): | |||
| 61 | - | t.Fatal("no config change") | |||
| 62 | } | 68 | } | ||
| 63 | } | 69 | } | ||
| 64 | receive("#000000") | 70 | receive("#000000") | ||
M internal/adapters/wayland/activation_test.go +2 -6
| @@ -95,9 +95,7 @@ func TestActivationNeedsFocusedRequester(t *testing.T) { | |||
| 95 | 95 | ||
| 96 | 96 | // The focused client's token activates, once. | |
| 97 | 97 | commands <- ports.FocusWindow{ID: first.ID} | |
| 98 | - | if err := c.Roundtrip(); err != nil { | |
| 99 | - | t.Fatal(err) | |
| 100 | - | } | |
| 98 | + | waitFocus(t, s, first.ID) | |
| 101 | 99 | token = newToken(t, c, manager) | |
| 102 | 100 | requestProtocol(t, c, manager, xdgactivation.ActivationV1RequestActivate, token, surf) | |
| 103 | 101 | activated(t, events, second.ID) | |
| @@ -120,9 +118,7 @@ func TestActivationAcrossClients(t *testing.T) { | |||
| 120 | 118 | managerA := bindProtocol(t, a, "xdg_activation_v1") | |
| 121 | 119 | managerB := bindProtocol(t, b, "xdg_activation_v1") | |
| 122 | 120 | commands <- ports.FocusWindow{ID: winA.ID} | |
| 123 | - | if err := a.Roundtrip(); err != nil { | |
| 124 | - | t.Fatal(err) | |
| 125 | - | } | |
| 121 | + | waitFocus(t, s, winA.ID) | |
| 126 | 122 | token := newToken(t, b, managerB) | |
| 127 | 123 | requestProtocol(t, b, managerB, xdgactivation.ActivationV1RequestActivate, token, surfB) | |
| 128 | 124 | noActivation(t, b, events) | |
| @@ -95,9 +95,7 @@ func TestActivationNeedsFocusedRequester(t *testing.T) { | |||||
| 95 | 95 | ||||
| 96 | // The focused client's token activates, once. | 96 | // The focused client's token activates, once. | ||
| 97 | commands <- ports.FocusWindow{ID: first.ID} | 97 | commands <- ports.FocusWindow{ID: first.ID} | ||
| 98 | - | if err := c.Roundtrip(); err != nil { | 98 | + | waitFocus(t, s, first.ID) |
| 99 | - | t.Fatal(err) | |||
| 100 | - | } | |||
| 101 | token = newToken(t, c, manager) | 99 | token = newToken(t, c, manager) | ||
| 102 | requestProtocol(t, c, manager, xdgactivation.ActivationV1RequestActivate, token, surf) | 100 | requestProtocol(t, c, manager, xdgactivation.ActivationV1RequestActivate, token, surf) | ||
| 103 | activated(t, events, second.ID) | 101 | activated(t, events, second.ID) | ||
| @@ -120,9 +118,7 @@ func TestActivationAcrossClients(t *testing.T) { | |||||
| 120 | managerA := bindProtocol(t, a, "xdg_activation_v1") | 118 | managerA := bindProtocol(t, a, "xdg_activation_v1") | ||
| 121 | managerB := bindProtocol(t, b, "xdg_activation_v1") | 119 | managerB := bindProtocol(t, b, "xdg_activation_v1") | ||
| 122 | commands <- ports.FocusWindow{ID: winA.ID} | 120 | commands <- ports.FocusWindow{ID: winA.ID} | ||
| 123 | - | if err := a.Roundtrip(); err != nil { | 121 | + | waitFocus(t, s, winA.ID) |
| 124 | - | t.Fatal(err) | |||
| 125 | - | } | |||
| 126 | token := newToken(t, b, managerB) | 122 | token := newToken(t, b, managerB) | ||
| 127 | requestProtocol(t, b, managerB, xdgactivation.ActivationV1RequestActivate, token, surfB) | 123 | requestProtocol(t, b, managerB, xdgactivation.ActivationV1RequestActivate, token, surfB) | ||
| 128 | noActivation(t, b, events) | 124 | noActivation(t, b, events) | ||