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