chiark / gitweb /
test to verify current dbversion behavior
[disorder] / tests / dtest.py
1 #-*-python-*-
2
3 """Utility module used by tests"""
4
5 import os,os.path,subprocess,sys,disorder,unicodedata
6
7 def copyfile(a,b):
8     """copyfile(A, B)
9 Copy A to B."""
10     open(b,"w").write(open(a).read())
11
12 def maketrack(s):
13     """maketrack(S)
14
15 Make track with relative path S exist"""
16     trackpath = "%s/%s" % (tracks, s)
17     trackdir = os.path.dirname(trackpath)
18     if not os.path.exists(trackdir):
19         os.makedirs(trackdir)
20     copyfile("%s/sounds/slap.ogg" % topsrcdir, trackpath)
21     # We record the tracks we created so they can be tested against
22     # server responses.  We put them into NFC since that's what the server
23     # uses internally.
24     bits = unicodedata.normalize("NFC",
25                                  unicode(s, "UTF-8")).split('/')
26     dp = tracks
27     for d in bits [0:-1]:
28         dd = "%s/%s" % (dp,  d)
29         if dp not in dirs_by_dir:
30             dirs_by_dir[dp] = []
31         if dd not in dirs_by_dir[dp]:
32             dirs_by_dir[dp].append(dd)
33         dp = "%s/%s" % (dp, d)
34     if dp not in files_by_dir:
35         files_by_dir[dp] = []
36     files_by_dir[dp].append("%s/%s" % (dp, bits[-1]))
37
38 def stdtracks():
39     # We create some tracks with non-ASCII characters in the name and
40     # we (currently) force UTF-8.
41     #
42     # On a traditional UNIX filesystem, that treats filenames as byte strings
43     # with special significant for '/', this should just work, though the
44     # names will look wrong to ls(1) in a non UTF-8 locale.
45     #
46     # On Apple HFS+ filenames normalized to a decomposed form that isn't quite
47     # NFD, so our attempts to have both normalized and denormalized filenames
48     # is frustrated.  Provided we test on traditional filesytsems too this
49     # shouldn't be a problem.
50     # (See http://developer.apple.com/qa/qa2001/qa1173.html)
51
52     global dirs_by_dir, files_by_dir
53     dirs_by_dir={}
54     files_by_dir={}
55     
56     # C3 8C = 00CC LATIN CAPITAL LETTER I WITH GRAVE
57     # (in NFC)
58     maketrack("Joe Bloggs/First Album/01:F\xC3\x8Crst track.ogg")
59
60     maketrack("Joe Bloggs/First Album/02:Second track.ogg")
61
62     # CC 81 = 0301 COMBINING ACUTE ACCENT
63     # (giving an NFD i-acute)
64     maketrack("Joe Bloggs/First Album/03:ThI\xCC\x81rd track.ogg")
65     # ...hopefuly giving C3 8D = 00CD LATIN CAPITAL LETTER I WITH ACUTE
66     maketrack("Joe Bloggs/First Album/04:Fourth track.ogg")
67     maketrack("Joe Bloggs/First Album/05:Fifth track.ogg")
68     maketrack("Joe Bloggs/Second Album/01:First track.ogg")
69     maketrack("Joe Bloggs/Second Album/02:Second track.ogg")
70     maketrack("Joe Bloggs/Second Album/03:Third track.ogg")
71     maketrack("Joe Bloggs/Second Album/04:Fourth track.ogg")
72     maketrack("Joe Bloggs/Second Album/05:Fifth track.ogg")
73     maketrack("Joe Bloggs/Third Album/01:First track.ogg")
74     maketrack("Joe Bloggs/Third Album/02:Second track.ogg")
75     maketrack("Joe Bloggs/Third Album/03:Third track.ogg")
76     maketrack("Joe Bloggs/Third Album/04:Fourth track.ogg")
77     maketrack("Joe Bloggs/Third Album/05:Fifth track.ogg")
78     maketrack("Fred Smith/Boring/01:Dull.ogg")
79     maketrack("Fred Smith/Boring/02:Tedious.ogg")
80     maketrack("Fred Smith/Boring/03:Drum Solo.ogg")
81     maketrack("Fred Smith/Boring/04:Yawn.ogg")
82     maketrack("misc/blahblahblah.ogg")
83     maketrack("Various/Greatest Hits/01:Jim Whatever - Spong.ogg")
84     maketrack("Various/Greatest Hits/02:Joe Bloggs - Yadda.ogg")
85
86 def notracks():
87     pass
88
89 def common_setup():
90     remove_dir(testroot)
91     os.mkdir(testroot)
92     open("%s/config" % testroot, "w").write(
93     """player *.ogg shell 'echo "$TRACK" >> %s/played.log'
94 home %s
95 collection fs UTF-8 %s/tracks
96 scratch %s/scratch.ogg
97 gap 0
98 stopword 01 02 03 04 05 06 07 08 09 10
99 stopword 1 2 3 4 5 6 7 8 9
100 stopword 11 12 13 14 15 16 17 18 19 20
101 stopword 21 22 23 24 25 26 27 28 29 30
102 stopword the a an and to too in on of we i am as im for is
103 username fred
104 password fredpass
105 allow fred fredpass
106 plugins ../plugins
107 player *.mp3 execraw disorder-decode
108 player *.ogg execraw disorder-decode
109 player *.wav execraw disorder-decode
110 player *.flac execraw disorder-decode
111 tracklength *.mp3 disorder-tracklength
112 tracklength *.ogg disorder-tracklength
113 tracklength *.wav disorder-tracklength
114 tracklength *.flac disorder-tracklength
115 """ % (testroot, testroot, testroot, testroot))
116     copyfile("%s/sounds/scratch.ogg" % topsrcdir,
117              "%s/scratch.ogg" % testroot)
118
119 def start_daemon():
120     """start_daemon()
121 Start the daemon."""
122     global daemon,errs
123     assert daemon is None
124     server = None
125     print " starting daemon"
126     daemon = subprocess.Popen(["disorderd",
127                                "--foreground",
128                                "--config", "%s/config" % testroot],
129                               stderr=errs)
130
131 def stop_daemon():
132     """stop_daemon()
133
134 Stop the daemon if it has not stopped already"""
135     global daemon
136     assert daemon is not None
137     rc = daemon.poll()
138     if rc == None:
139         print " stopping daemon"
140         os.kill(daemon.pid, 15)
141         rc = daemon.wait()
142     print " daemon has stopped"
143     daemon = None
144
145 def run(test, setup=None, report=True, name=None): 
146     global tests,errs
147     tests += 1
148     if setup == None:
149         setup = stdtracks
150     errs = open("%s.log" % test.__name__, "w") # HNGGGH.  nO.
151     disorder._configfile = "%s/config" % testroot
152     disorder._userconf = False
153     common_setup()
154     setup()
155     try:
156         try:
157             test()
158         except AssertionError, e:
159             global failures
160             failures += 1
161             print e
162     finally:
163         if daemon is not None:
164             stop_daemon()
165     if report:
166         if failures:
167             print " FAILED"
168             sys.exit(1)
169         else:
170             print " OK"
171
172 def remove_dir(d):
173     """remove_dir(D)
174
175 Recursively delete directory D"""
176     if os.path.lexists(d):
177         if os.path.isdir(d):
178             for dd in os.listdir(d):
179                 remove_dir("%s/%s" % (d, dd))
180             os.rmdir(d)
181         else:
182             os.remove(d)
183
184 # -----------------------------------------------------------------------------
185 # Common setup
186
187 tests = 0
188 failures = 0
189 daemon = None
190 testroot = "%s/testroot" % os.getcwd()
191 tracks = "%s/tracks" % testroot
192 topsrcdir = os.path.abspath(os.getenv("topsrcdir"))