1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import dircache
19 import os.path
20 from qm.test.database import *
21 from qm.test.suite import Suite
22 from qm.fields import *
23 import qm.test.database
24
25
26
27
28
30 """A 'MountDatabase' contains other databases.
31
32 Every contained database has a "mount point", which is a label
33 giving the root of the database. A test with the ID "x" in a
34 database with a mount point of "y" has the ID "x.y" in the
35 containing database.
36
37 The contained databases are found by looking for subdirectories of
38 the 'MountDatabase' directory. Every immediate subdirectory which
39 is itself a QMTest database is mounted; its mount point is the
40 name of the subdirectory."""
41
43 """A 'MountedSuite' is a suite from a mounted database."""
44
45 - def __init__(self, database, suite_id, joiner, suite):
53
54
58
59
61
62 return map(self.__joiner, self.__suite.GetTestIds())
63
64
66
67 return map(self.__joiner, self.__suite.GetSuiteIds())
68
69
70 mounts = DictionaryField(key_field = TextField(),
71 value_field = TextField(),
72 description=\
73 """Dictionary mapping mount points to (sub-)database paths.
74 If empty, the database directory is scanned for subdirectories.""")
75
76
78
79
80
81
82 label_class = None
83 implicit = False
84
85 self.mounts = arguments.pop('mounts', {})
86 self._mounts = {}
87 if not self.mounts:
88
89 implicit = True
90 self.mounts = dict([(d, os.path.join(path, d))
91 for d in dircache.listdir(path)])
92 else:
93
94 tmp = {}
95 for k,v in self.mounts.iteritems():
96 tmp[k] = os.path.join(path, v)
97 self.mounts = tmp
98
99 for k,v in self.mounts.iteritems():
100 if is_database(v):
101 db = load_database(v)
102 self._mounts[k] = db
103 if not label_class:
104 label_class = db.label_class
105 elif label_class != db.label_class:
106 raise QMException, \
107 "mounted databases use differing label classes"
108 elif not implicit:
109 raise QMException, "%s does not contain a test database"%v
110
111
112 arguments["modifiable"] = "false"
113 if label_class:
114 arguments["label_class"] = label_class
115
116 Database.__init__(self, path, arguments)
117
118
119
120 - def GetIds(self, kind, directory="", scan_subdirs=1):
131
152
153
166
167
180
181
188
189
191
192 paths = []
193 for db in self._mounts.values():
194 paths.extend(db.GetClassPaths())
195 paths.append(get_configuration_directory(db.GetPath()))
196 return paths
197
198
200 """Adjust the resource IDs stored in the 'arguments'.
201
202 'joiner' -- A function of one argument which prepends the
203 label for a mount point to the label it is given.
204
205 'arguments' -- The arguments to a test or resource class.
206
207 Modifies the arguments to contain resource names that are
208 relative to the containing database."""
209
210 resources = arguments.get(Runnable.RESOURCE_FIELD_ID)
211 if resources:
212 new_resources = map(joiner, resources)
213 arguments[Runnable.RESOURCE_FIELD_ID] = new_resources
214
215
217 """Return 'item_id' from a mounted database.
218
219 'kind' -- The kind of item to return.
220
221 'item_id' -- The name of the item, in the containing
222 database.
223
224 returns -- A tuple '(joiner, item). The 'item' will be from
225 one of the mounted databases. 'joiner' is a function of one
226 argument which prepends the mount point to its argument."""
227
228 try:
229 database, joiner, item_id = self._SelectDatabase(item_id)
230
231
232 try:
233 item = database.GetItem(kind, item_id)
234 except NoSuchItemError, e:
235
236 e.item_id = joiner(item_id)
237 raise
238
239 return joiner, item
240 except:
241 raise Database._item_exceptions[kind](item_id)
242
243
245 """Return the contained database in which 'item_id' can be found.
246
247 'item_id' -- The name of an item in this database.
248
249 returns -- A tuple '(database, joiner, id)' where 'database'
250 is a 'Database', 'joiner' is a function of one argument which
251 prepends the mount point to a label, and 'id' is the portion
252 of 'item_id' that remains after stripping off the mount point
253 of 'database'. If 'item_id' does not correspond to any mount
254 point, an exception is raised."""
255
256 mount_point, item_id = self.SplitLabelLeft(item_id)
257 db = self._mounts[mount_point]
258 return (db, lambda p: self.JoinLabels(mount_point, p), item_id)
259