From 2b2a5fed939a267d9ab95ce900a15bf11e108edf Mon Sep 17 00:00:00 2001 Message-Id: <2b2a5fed939a267d9ab95ce900a15bf11e108edf.1714493681.git.mdw@distorted.org.uk> From: Mark Wooding Date: Thu, 10 Jan 2008 14:39:37 +0000 Subject: [PATCH] More careful testing of scratching, and correctly handle the case where a track is scratched before the speaker process has got to grips with it. Organization: Straylight/Edgeware From: Richard Kettlewell --- lib/speaker-protocol.h | 4 +++ server/play.c | 5 ++++ server/speaker.c | 5 +++- tests/play.py | 57 ++++++++++++++++++++++++++---------------- 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/speaker-protocol.h b/lib/speaker-protocol.h index ac4fdf0..520a0c6 100644 --- a/lib/speaker-protocol.h +++ b/lib/speaker-protocol.h @@ -42,6 +42,7 @@ struct speaker_message { * - @ref SM_PAUSED * - @ref SM_FINISHED * - @ref SM_PLAYING + * - @ref SM_UNKNOWN */ int type; @@ -83,6 +84,9 @@ struct speaker_message { /** @brief Finished playing track @c id */ #define SM_FINISHED 129 +/** @brief Never heard of track @c id */ +#define SM_UNKNOWN 130 + /** @brief Currently track @c id, @c data seconds in * * This is sent from time to time while a track is playing. diff --git a/server/play.c b/server/play.c index fa46329..d73aec7 100644 --- a/server/play.c +++ b/server/play.c @@ -116,6 +116,11 @@ static int speaker_readable(ev_source *ev, int fd, D(("SM_FINISHED %s", sm.id)); finished(ev); break; + case SM_UNKNOWN: + /* we asked for an unknown track to be cancelled */ + if(playing && !strcmp(sm.id, playing->id)) + finished(ev); + break; case SM_PLAYING: /* track ID is playing, DATA seconds played */ D(("SM_PLAYING %s %ld", sm.id, sm.data)); diff --git a/server/speaker.c b/server/speaker.c index ae43f12..407b1d7 100644 --- a/server/speaker.c +++ b/server/speaker.c @@ -563,8 +563,11 @@ static void mainloop(void) { playing = 0; } destroy(t); - } else + } else { + sm.type = SM_UNKNOWN; + speaker_send(1, &sm); error(0, "SM_CANCEL for unknown track %s", sm.id); + } report(); break; case SM_RELOAD: diff --git a/tests/play.py b/tests/play.py index c638572..ce5cbb1 100755 --- a/tests/play.py +++ b/tests/play.py @@ -1,7 +1,7 @@ #! /usr/bin/env python # # This file is part of DisOrder. -# Copyright (C) 2007 Richard Kettlewell +# Copyright (C) 2007, 2008 Richard Kettlewell # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,9 +25,12 @@ def test(): dtest.start_daemon() dtest.create_user() c = disorder.client() + c.random_disable() + assert c.random_enabled() == False track = u"%s/Joe Bloggs/First Album/02:Second track.ogg" % dtest.tracks print " adding track to queue" c.disable() + assert c.enabled() == False c.play(track) print " checking track turned up in queue" q = c.queue() @@ -38,6 +41,7 @@ def test(): i = t['id'] print " waiting for track" c.enable() + assert c.enabled() == True p = c.playing() r = c.recent() while not((p is not None and p['id'] == i) @@ -54,33 +58,42 @@ def test(): assert len(ts) == 1, "check track appears exactly once in recent" t = ts[0] assert t['submitter'] == u'fred', "check recent entry submitter" - print " disabling play" - c.disable() - print " scratching current track" - p = c.playing() - i = p['id'] - c.scratch(i) - print " checking scratched track turned up in recent list" - while (p is not None and p['id'] == i): - time.sleep(1) + + print " testing scratches" + retry = False + while True: + c.disable() + print " starting a track" + c.play(track) + c.enable() p = c.playing() - r = c.recent() - ts = filter(lambda t: t['id'] == i, r) - assert len(ts) == 1, "check scratched track appears exactly once in recent" - assert ts[0]['state'] == 'scratched', "checking track scratched" + if p is None: + print " track played too quickly, trying again..." + continue + print " scratching track" + i = p['id'] + c.scratch(i) + print " waiting for track to finish" + p = c.playing() + while (p is not None and p['id'] == i): + time.sleep(1) + p = c.playing() + print " checking scratched track turned up in recent list" + r = c.recent() + ts = filter(lambda t: t['id'] == i, r) + assert len(ts) == 1, "check scratched track appears exactly once in recent" + if ts[0]['state'] == 'ok': + print " track played too quickly, trying again..." + continue + assert ts[0]['state'] == 'scratched', "checking track scratched" + break print " waiting for scratch to complete" - while (p is not None and p['state'] == 'isscratch'): + p = c.recent() + while p is not None: time.sleep(1) p = c.playing() assert p is None, "checking nothing is playing" - c.random_disable() - assert c.random_enabled() == False - assert c.enabled() == False - c.enable() assert c.enabled() == True - time.sleep(1) - p = c.playing() - assert p is None, "checking nothing playing when random disabled but playing enabled" c.random_enable() assert c.random_enabled() == True -- [mdw]