test(drm): fold the frame wake tests into one table
TestCompletedSendsFrameOnlyForAnimatingScene, TestCompletedFramesNeverBlock and TestCompletedWithoutFramesChannel are rows of TestCompletedFrames; each row keeps its flips and expected frames. The allocation test stays apart.
- commit
- 5273ef5a47f80d36ff119bba4932941e2523fae9
- author
- brice · · 2026-10-14 03:43 UTC
- committer
- brice · · 2026-10-14 04:34 UTC
- parent
- 4e9be6c
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +34 -38
M internal/adapters/drm/frames_test.go +34 -38
| @@ -7,45 +7,41 @@ import ( | |||
| 7 | 7 | "github.com/stretchr/testify/require" | |
| 8 | 8 | ) | |
| 9 | 9 | ||
| 10 | - | // A flip of an animating scene tells core the next frame is due; the flip | |
| 11 | - | // of any other frame does not. | |
| 12 | - | func TestCompletedSendsFrameOnlyForAnimatingScene(t *testing.T) { | |
| 13 | - | o, _, commits := testOutput(t) | |
| 14 | - | o.cursor = nil | |
| 15 | - | frames := make(chan ports.OutputFrame, 2) | |
| 16 | - | o.Frames = frames | |
| 17 | - | seen := map[ports.WindowID]uint64{} | |
| 18 | - | ||
| 19 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{})) | |
| 20 | - | require.True(t, o.completed(eventOf((*commits)[0]), seen)) | |
| 21 | - | require.Empty(t, frames, "a settled scene wakes nobody") | |
| 22 | - | ||
| 23 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | |
| 24 | - | require.True(t, o.completed(eventOf((*commits)[1]), seen)) | |
| 25 | - | require.Equal(t, []ports.OutputFrame{{Output: "DP-1"}}, drain(frames)) | |
| 26 | - | ||
| 27 | - | } | |
| 28 | - | ||
| 29 | - | // A frames channel core has not read stays full: the owner never waits. | |
| 30 | - | func TestCompletedFramesNeverBlock(t *testing.T) { | |
| 31 | - | o, _, commits := testOutput(t) | |
| 32 | - | o.cursor = nil | |
| 33 | - | frames := make(chan ports.OutputFrame, 1) | |
| 34 | - | o.Frames = frames | |
| 35 | - | seen := map[ports.WindowID]uint64{} | |
| 36 | - | for i := range 3 { | |
| 37 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | |
| 38 | - | require.True(t, o.completed(eventOf((*commits)[i]), seen)) | |
| 10 | + | // A flip of an animating scene tells core the next frame is due; the flip of | |
| 11 | + | // any other frame does not. A frames channel core has not read stays full: the | |
| 12 | + | // owner never waits. An output without a frames channel (tests, nobody to wake) | |
| 13 | + | // just flips. | |
| 14 | + | func TestCompletedFrames(t *testing.T) { | |
| 15 | + | tests := []struct { | |
| 16 | + | name string | |
| 17 | + | buffer int // frames channel capacity; 0: no channel | |
| 18 | + | animating []bool // the flips, one per frame | |
| 19 | + | want []ports.OutputFrame | |
| 20 | + | }{ | |
| 21 | + | {name: "a settled scene wakes nobody", buffer: 2, animating: []bool{false}}, | |
| 22 | + | {name: "an animating scene wakes core once", buffer: 2, animating: []bool{false, true}, want: []ports.OutputFrame{{Output: "DP-1"}}}, | |
| 23 | + | {name: "a full channel never blocks", buffer: 1, animating: []bool{true, true, true}, want: []ports.OutputFrame{{Output: "DP-1"}}}, | |
| 24 | + | {name: "no frames channel", animating: []bool{true}}, | |
| 25 | + | } | |
| 26 | + | for _, tt := range tests { | |
| 27 | + | t.Run(tt.name, func(t *testing.T) { | |
| 28 | + | o, _, commits := testOutput(t) | |
| 29 | + | o.cursor = nil | |
| 30 | + | var frames chan ports.OutputFrame | |
| 31 | + | if tt.buffer > 0 { | |
| 32 | + | frames = make(chan ports.OutputFrame, tt.buffer) | |
| 33 | + | o.Frames = frames | |
| 34 | + | } | |
| 35 | + | seen := map[ports.WindowID]uint64{} | |
| 36 | + | for i, animating := range tt.animating { | |
| 37 | + | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: animating})) | |
| 38 | + | require.True(t, o.completed(eventOf((*commits)[i]), seen)) | |
| 39 | + | } | |
| 40 | + | if frames != nil { | |
| 41 | + | require.Equal(t, tt.want, drain(frames)) | |
| 42 | + | } | |
| 43 | + | }) | |
| 39 | 44 | } | |
| 40 | - | require.Len(t, frames, 1) | |
| 41 | - | } | |
| 42 | - | ||
| 43 | - | // An output without a frames channel (tests, nobody to wake) just flips. | |
| 44 | - | func TestCompletedWithoutFramesChannel(t *testing.T) { | |
| 45 | - | o, _, commits := testOutput(t) | |
| 46 | - | o.cursor = nil | |
| 47 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | |
| 48 | - | require.True(t, o.completed(eventOf((*commits)[0]), map[ports.WindowID]uint64{})) | |
| 49 | 45 | } | |
| 50 | 46 | ||
| 51 | 47 | func drain(ch chan ports.OutputFrame) []ports.OutputFrame { | |
| @@ -7,45 +7,41 @@ import ( | |||||
| 7 | "github.com/stretchr/testify/require" | 7 | "github.com/stretchr/testify/require" | ||
| 8 | ) | 8 | ) | ||
| 9 | 9 | ||||
| 10 | - | // A flip of an animating scene tells core the next frame is due; the flip | 10 | + | // A flip of an animating scene tells core the next frame is due; the flip of |
| 11 | - | // of any other frame does not. | 11 | + | // any other frame does not. A frames channel core has not read stays full: the |
| 12 | - | func TestCompletedSendsFrameOnlyForAnimatingScene(t *testing.T) { | 12 | + | // owner never waits. An output without a frames channel (tests, nobody to wake) |
| 13 | - | o, _, commits := testOutput(t) | 13 | + | // just flips. |
| 14 | - | o.cursor = nil | 14 | + | func TestCompletedFrames(t *testing.T) { |
| 15 | - | frames := make(chan ports.OutputFrame, 2) | 15 | + | tests := []struct { |
| 16 | - | o.Frames = frames | 16 | + | name string |
| 17 | - | seen := map[ports.WindowID]uint64{} | 17 | + | buffer int // frames channel capacity; 0: no channel |
| 18 | - | 18 | + | animating []bool // the flips, one per frame | |
| 19 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{})) | 19 | + | want []ports.OutputFrame |
| 20 | - | require.True(t, o.completed(eventOf((*commits)[0]), seen)) | 20 | + | }{ |
| 21 | - | require.Empty(t, frames, "a settled scene wakes nobody") | 21 | + | {name: "a settled scene wakes nobody", buffer: 2, animating: []bool{false}}, |
| 22 | - | 22 | + | {name: "an animating scene wakes core once", buffer: 2, animating: []bool{false, true}, want: []ports.OutputFrame{{Output: "DP-1"}}}, | |
| 23 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | 23 | + | {name: "a full channel never blocks", buffer: 1, animating: []bool{true, true, true}, want: []ports.OutputFrame{{Output: "DP-1"}}}, |
| 24 | - | require.True(t, o.completed(eventOf((*commits)[1]), seen)) | 24 | + | {name: "no frames channel", animating: []bool{true}}, |
| 25 | - | require.Equal(t, []ports.OutputFrame{{Output: "DP-1"}}, drain(frames)) | 25 | + | } |
| 26 | - | 26 | + | for _, tt := range tests { | |
| 27 | - | } | 27 | + | t.Run(tt.name, func(t *testing.T) { |
| 28 | - | 28 | + | o, _, commits := testOutput(t) | |
| 29 | - | // A frames channel core has not read stays full: the owner never waits. | 29 | + | o.cursor = nil |
| 30 | - | func TestCompletedFramesNeverBlock(t *testing.T) { | 30 | + | var frames chan ports.OutputFrame |
| 31 | - | o, _, commits := testOutput(t) | 31 | + | if tt.buffer > 0 { |
| 32 | - | o.cursor = nil | 32 | + | frames = make(chan ports.OutputFrame, tt.buffer) |
| 33 | - | frames := make(chan ports.OutputFrame, 1) | 33 | + | o.Frames = frames |
| 34 | - | o.Frames = frames | 34 | + | } |
| 35 | - | seen := map[ports.WindowID]uint64{} | 35 | + | seen := map[ports.WindowID]uint64{} |
| 36 | - | for i := range 3 { | 36 | + | for i, animating := range tt.animating { |
| 37 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | 37 | + | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: animating})) |
| 38 | - | require.True(t, o.completed(eventOf((*commits)[i]), seen)) | 38 | + | require.True(t, o.completed(eventOf((*commits)[i]), seen)) |
| 39 | + | } | |||
| 40 | + | if frames != nil { | |||
| 41 | + | require.Equal(t, tt.want, drain(frames)) | |||
| 42 | + | } | |||
| 43 | + | }) | |||
| 39 | } | 44 | } | ||
| 40 | - | require.Len(t, frames, 1) | |||
| 41 | - | } | |||
| 42 | - | ||||
| 43 | - | // An output without a frames channel (tests, nobody to wake) just flips. | |||
| 44 | - | func TestCompletedWithoutFramesChannel(t *testing.T) { | |||
| 45 | - | o, _, commits := testOutput(t) | |||
| 46 | - | o.cursor = nil | |||
| 47 | - | require.NoError(t, o.commitFrame(70, nil, false, false, pendingFrame{animating: true})) | |||
| 48 | - | require.True(t, o.completed(eventOf((*commits)[0]), map[ports.WindowID]uint64{})) | |||
| 49 | } | 45 | } | ||
| 50 | 46 | ||||
| 51 | func drain(ch chan ports.OutputFrame) []ports.OutputFrame { | 47 | func drain(ch chan ports.OutputFrame) []ports.OutputFrame { | ||