audio: run TestPlayOnIdleContext on the fake clock of synctest
The test was added after the survey in #3716, and waits on real time in the same way. Updates #3716
This commit is contained in:
1 parent
d22b1a2b09
commit
fab8fc22e0
1 file changed
+41
-39
+41
-39
@@ -879,52 +879,54 @@ func TestPlayerErrorDoesNotStopOtherPlayers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPlayOnIdleContext(t *testing.T) {
|
func TestPlayOnIdleContext(t *testing.T) {
|
||||||
setup()
|
synctest.Test(t, func(t *testing.T) {
|
||||||
defer teardown()
|
setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
// The first update creates the audio device, so that the players below play for real.
|
// The first update creates the audio device, so that the players below play for real.
|
||||||
if err := audio.UpdateForTesting(); err != nil {
|
if err := audio.UpdateForTesting(); err != nil {
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// waitUntil polls cond until it holds or the deadline passes, and reports whether it held.
|
|
||||||
// The deadline is generous because time.Sleep has a several-millisecond floor on browsers.
|
|
||||||
waitUntil := func(cond func() bool) bool {
|
|
||||||
deadline := time.Now().Add(10 * time.Second)
|
|
||||||
for time.Now().Before(deadline) {
|
|
||||||
if cond() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
time.Sleep(5 * time.Millisecond)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A player's position is advanced only by the context, so a growing position shows that the
|
|
||||||
// context updates the player. The second round starts a player after the context has dropped
|
|
||||||
// the finished player of the first round, that is, after it went idle by itself.
|
|
||||||
for i := range 2 {
|
|
||||||
// Let the context settle into idling with no player to update.
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
|
|
||||||
// 44100 [Hz] * 4 [bytes/sample] is one second of 16bit stereo audio.
|
|
||||||
p, err := context.NewPlayer(bytes.NewReader(make([]byte, 44100*4)))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
p.Play()
|
|
||||||
|
|
||||||
if !waitUntil(func() bool { return p.Position() > 0 }) {
|
// waitUntil polls cond until it holds or the deadline passes, and reports whether it held.
|
||||||
t.Errorf("round %d: Position() did not advance after Play on an idle context", i)
|
// The test runs on the fake clock of synctest, so the deadline does not take real time.
|
||||||
return
|
waitUntil := func(cond func() bool) bool {
|
||||||
|
deadline := time.Now().Add(10 * time.Second)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
if cond() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
time.Sleep(5 * time.Millisecond)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// The next round needs the context to be idle again, which is only possible once the
|
// A player's position is advanced only by the context, so a growing position shows that the
|
||||||
// context has dropped the finished player.
|
// context updates the player. The second round starts a player after the context has dropped
|
||||||
if !waitUntil(func() bool { return audio.PlayersCountForTesting() == 0 }) {
|
// the finished player of the first round, that is, after it went idle by itself.
|
||||||
t.Fatalf("round %d: time out: the player did not finish", i)
|
for i := range 2 {
|
||||||
|
// Let the context settle into idling with no player to update.
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
// 44100 [Hz] * 4 [bytes/sample] is one second of 16bit stereo audio.
|
||||||
|
p, err := context.NewPlayer(bytes.NewReader(make([]byte, 44100*4)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
p.Play()
|
||||||
|
|
||||||
|
if !waitUntil(func() bool { return p.Position() > 0 }) {
|
||||||
|
t.Errorf("round %d: Position() did not advance after Play on an idle context", i)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The next round needs the context to be idle again, which is only possible once the
|
||||||
|
// context has dropped the finished player.
|
||||||
|
if !waitUntil(func() bool { return audio.PlayersCountForTesting() == 0 }) {
|
||||||
|
t.Fatalf("round %d: time out: the player did not finish", i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func callWithTimeout(t *testing.T, name string, f func() error) error {
|
func callWithTimeout(t *testing.T, name string, f func() error) error {
|
||||||
|
|||||||
Reference in new issue
Block a user