--- /dev/null
- dtest.run(test)
+#! /usr/bin/env python
+#
+# This file is part of DisOrder.
+# Copyright (C) 2007 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+#
+import dtest,time,disorder,sys,re
+
+def test():
+ """Database version tests"""
+ # Start up with dbversion 1
+ config = "%s/config" % dtest.testroot
+ configsave = "%s.save" % config
+ dtest.copyfile(config, configsave)
+ open(config, "a").write("dbversion 1\n")
+ dtest.start_daemon()
+ time.sleep(2)
+ dtest.stop_daemon()
+ # Revert to default configuration
+ dtest.copyfile(configsave, config)
+ dtest.start_daemon()
+ time.sleep(2)
+ c = disorder.client()
+ try:
+ v = c.version()
+ print "unexpected success"
+ ok = False
+ except disorder.communicationError, e:
+ if re.search("connection refused", str(e)):
+ print "unexpected error: %s" % e
+ ok = False
+ else:
+ ok = True
+ dtest.stop_daemon()
+ if not ok:
+ sys.exit(1)
+
+if __name__ == '__main__':
++ dtest.run()
"""Utility module used by tests"""
-import os,os.path,subprocess,sys,re
+import os,os.path,subprocess,sys,re,unicodedata
def fatal(s):
"""Write an error message and exit"""
if not os.path.exists(trackdir):
os.makedirs(trackdir)
copyfile("%s/sounds/slap.ogg" % top_srcdir, trackpath)
+ # We record the tracks we created so they can be tested against
+ # server responses. We put them into NFC since that's what the server
+ # uses internally.
+ bits = unicodedata.normalize("NFC",
+ unicode(s, "UTF-8")).split('/')
+ dp = tracks
+ for d in bits [0:-1]:
+ dd = "%s/%s" % (dp, d)
+ if dp not in dirs_by_dir:
+ dirs_by_dir[dp] = []
+ if dd not in dirs_by_dir[dp]:
+ dirs_by_dir[dp].append(dd)
+ dp = "%s/%s" % (dp, d)
+ if dp not in files_by_dir:
+ files_by_dir[dp] = []
+ files_by_dir[dp].append("%s/%s" % (dp, bits[-1]))
def stdtracks():
- maketrack("Joe Bloggs/First Album/01:First track.ogg")
+ # We create some tracks with non-ASCII characters in the name and
+ # we (currently) force UTF-8.
+ #
+ # On a traditional UNIX filesystem, that treats filenames as byte strings
+ # with special significant for '/', this should just work, though the
+ # names will look wrong to ls(1) in a non UTF-8 locale.
+ #
+ # On Apple HFS+ filenames normalized to a decomposed form that isn't quite
+ # NFD, so our attempts to have both normalized and denormalized filenames
+ # is frustrated. Provided we test on traditional filesytsems too this
+ # shouldn't be a problem.
+ # (See http://developer.apple.com/qa/qa2001/qa1173.html)
+
+ global dirs_by_dir, files_by_dir
+ dirs_by_dir={}
+ files_by_dir={}
+
+ # C3 8C = 00CC LATIN CAPITAL LETTER I WITH GRAVE
+ # (in NFC)
+ maketrack("Joe Bloggs/First Album/01:F\xC3\x8Crst track.ogg")
+
maketrack("Joe Bloggs/First Album/02:Second track.ogg")
- maketrack("Joe Bloggs/First Album/03:Third track.ogg")
+
+ # CC 81 = 0301 COMBINING ACUTE ACCENT
+ # (giving an NFD i-acute)
+ maketrack("Joe Bloggs/First Album/03:ThI\xCC\x81rd track.ogg")
+ # ...hopefuly giving C3 8D = 00CD LATIN CAPITAL LETTER I WITH ACUTE
maketrack("Joe Bloggs/First Album/04:Fourth track.ogg")
maketrack("Joe Bloggs/First Album/05:Fifth track.ogg")
maketrack("Joe Bloggs/Second Album/01:First track.ogg")
maketrack("misc/blahblahblah.ogg")
maketrack("Various/Greatest Hits/01:Jim Whatever - Spong.ogg")
maketrack("Various/Greatest Hits/02:Joe Bloggs - Yadda.ogg")
-
- def notracks():
- pass
--
++
def common_setup():
remove_dir(testroot)
os.mkdir(testroot)
username fred
password fredpass
allow fred fredpass
- plugins ../plugins
+ plugins %s/plugins
player *.mp3 execraw disorder-decode
player *.ogg execraw disorder-decode
player *.wav execraw disorder-decode
tracklength *.ogg disorder-tracklength
tracklength *.wav disorder-tracklength
tracklength *.flac disorder-tracklength
- """ % (testroot, testroot, testroot, testroot))
+ """ % (testroot, testroot, testroot, testroot, top_builddir))
copyfile("%s/sounds/scratch.ogg" % top_srcdir,
"%s/scratch.ogg" % testroot)
def start_daemon():
"""start_daemon()
+
Start the daemon."""
- global daemon,errs
- assert daemon is None
- server = None
+ global daemon, errs
+ assert daemon == None
print " starting daemon"
daemon = subprocess.Popen(["disorderd",
"--foreground",
"--config", "%s/config" % testroot],
stderr=errs)
- disorder._configfile = "%s/config" % testroot
- disorder._userconf = False
def stop_daemon():
"""stop_daemon()
Stop the daemon if it has not stopped already"""
global daemon
- assert daemon is not None
+ if daemon == None:
+ return
rc = daemon.poll()
if rc == None:
print " stopping daemon"
print " daemon has stopped"
daemon = None
- def run(test, setup=None, report=True, name=None):
- global tests,errs
+ def run(module=None, report=True):
+ """dtest.run(MODULE)
+
+ Run the test in MODULE. This can be a string (in which case the module
+ will be imported) or a module object."""
+ global tests
tests += 1
- if setup == None:
- setup = stdtracks
- errs = open("%s.log" % test.__name__, "w")
+ # Locate the test module
+ if module is None:
+ # We're running a test stand-alone
+ import __main__
+ module = __main__
+ name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
+ else:
+ # We've been passed a module or a module name
+ if type(module) == str:
+ module = __import__(module)
+ name = module.__name__
+ # Open the error log
+ global errs
+ errs = open("%s.log" % name, "w")
+ # Ensure that disorder.py uses the test installation
disorder._configfile = "%s/config" % testroot
disorder._userconf = False
+ # Make config file etc
common_setup()
- setup()
+ # Create some standard tracks
+ stdtracks()
try:
try:
- test()
+ module.test()
except AssertionError, e:
global failures
failures += 1
print e
finally:
- if daemon is not None:
- stop_daemon()
+ stop_daemon()
if report:
if failures:
print " FAILED"
--- /dev/null
- dtest.run(test)
+#! /usr/bin/env python
+#
+# This file is part of DisOrder.
+# Copyright (C) 2007 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+#
+import dtest,time,disorder,sys
+
+def test():
+ """Check that the file listing comes out right"""
+ dtest.start_daemon()
+ time.sleep(5) # give rescan a chance
+ c = disorder.client()
+ failures = 0
+ for d in dtest.dirs_by_dir:
+ xdirs = dtest.dirs_by_dir[d]
+ dirs = c.directories(d)
+ xdirs.sort()
+ dirs.sort()
+ if dirs != xdirs:
+ print
+ print "directory: %s" % d
+ print "expected: %s" % xdirs
+ print "got: %s" % dirs
+ failures += 1
+ for d in dtest.files_by_dir:
+ xfiles = dtest.files_by_dir[d]
+ files = c.files(d)
+ xfiles.sort()
+ files.sort()
+ if files != xfiles:
+ print
+ print "directory: %s" % d
+ print "expected: %s" % xfiles
+ print "got: %s" % files
+ failures += 1
+ if failures:
+ print
+ sys.exit(1)
+
+if __name__ == '__main__':
++ dtest.run()