blob: 72c897fbc6c4e1445f0b2d3413d6588eaaf05de8 [file] [log] [blame]
mbligh65acae52008-04-24 20:21:55 +00001import re, os, sys, types, time, random
mbligh96cf0512008-04-17 15:25:38 +00002
3import common
4from autotest_lib.client.common_lib import global_config
jamesrena12b8a02010-06-16 23:28:23 +00005from autotest_lib.tko import utils
mbligh96cf0512008-04-17 15:25:38 +00006
mblighed4d6dd2008-02-27 16:49:43 +00007
mblighaea09602008-04-16 22:59:37 +00008class MySQLTooManyRows(Exception):
jadmanski0afbb632008-06-06 21:10:57 +00009 pass
mblighaea09602008-04-16 22:59:37 +000010
mblighd5c33db2006-10-08 21:34:16 +000011
mbligh7636b3a2008-06-11 15:44:01 +000012class db_sql(object):
jadmanski0afbb632008-06-06 21:10:57 +000013 def __init__(self, debug=False, autocommit=True, host=None,
14 database=None, user=None, password=None):
15 self.debug = debug
16 self.autocommit = autocommit
17 self._load_config(host, database, user, password)
mbligh96cf0512008-04-17 15:25:38 +000018
jadmanski0afbb632008-06-06 21:10:57 +000019 self.con = None
20 self._init_db()
mblighd5c33db2006-10-08 21:34:16 +000021
jadmanski0afbb632008-06-06 21:10:57 +000022 # if not present, insert statuses
23 self.status_idx = {}
24 self.status_word = {}
showardeab66ce2009-12-23 00:03:56 +000025 status_rows = self.select('status_idx, word', 'tko_status', None)
jadmanski0afbb632008-06-06 21:10:57 +000026 for s in status_rows:
27 self.status_idx[s[1]] = s[0]
28 self.status_word[s[0]] = s[1]
mbligh048e1c92007-10-07 00:10:33 +000029
jadmanski0afbb632008-06-06 21:10:57 +000030 machine_map = os.path.join(os.path.dirname(__file__),
31 'machines')
32 if os.path.exists(machine_map):
33 self.machine_map = machine_map
34 else:
35 self.machine_map = None
36 self.machine_group = {}
mbligh048e1c92007-10-07 00:10:33 +000037
mbligh8e1ab172007-09-13 17:29:56 +000038
jadmanski0afbb632008-06-06 21:10:57 +000039 def _load_config(self, host, database, user, password):
40 # grab the global config
41 get_value = global_config.global_config.get_config_value
mbligh65acae52008-04-24 20:21:55 +000042
jadmanski0afbb632008-06-06 21:10:57 +000043 # grab the host, database
44 if host:
45 self.host = host
46 else:
showard250d84d2010-01-12 21:59:48 +000047 self.host = get_value("AUTOTEST_WEB", "host")
jadmanski0afbb632008-06-06 21:10:57 +000048 if database:
49 self.database = database
50 else:
showard250d84d2010-01-12 21:59:48 +000051 self.database = get_value("AUTOTEST_WEB", "database")
mbligh65acae52008-04-24 20:21:55 +000052
jadmanski0afbb632008-06-06 21:10:57 +000053 # grab the user and password
54 if user:
55 self.user = user
56 else:
showard250d84d2010-01-12 21:59:48 +000057 self.user = get_value("AUTOTEST_WEB", "user")
mblighdc2c9bb2008-12-22 14:47:35 +000058 if password is not None:
jadmanski0afbb632008-06-06 21:10:57 +000059 self.password = password
60 else:
showard250d84d2010-01-12 21:59:48 +000061 self.password = get_value("AUTOTEST_WEB", "password")
mbligh65acae52008-04-24 20:21:55 +000062
jadmanski0afbb632008-06-06 21:10:57 +000063 # grab the timeout configuration
showard250d84d2010-01-12 21:59:48 +000064 self.query_timeout = get_value("AUTOTEST_WEB", "query_timeout",
jadmanski0afbb632008-06-06 21:10:57 +000065 type=int, default=3600)
showard250d84d2010-01-12 21:59:48 +000066 self.min_delay = get_value("AUTOTEST_WEB", "min_retry_delay", type=int,
jadmanski0afbb632008-06-06 21:10:57 +000067 default=20)
showard250d84d2010-01-12 21:59:48 +000068 self.max_delay = get_value("AUTOTEST_WEB", "max_retry_delay", type=int,
jadmanski0afbb632008-06-06 21:10:57 +000069 default=60)
mbligh65acae52008-04-24 20:21:55 +000070
71
jadmanski0afbb632008-06-06 21:10:57 +000072 def _init_db(self):
73 # make sure we clean up any existing connection
74 if self.con:
75 self.con.close()
76 self.con = None
mbligh65acae52008-04-24 20:21:55 +000077
jadmanski0afbb632008-06-06 21:10:57 +000078 # create the db connection and cursor
79 self.con = self.connect(self.host, self.database,
80 self.user, self.password)
81 self.cur = self.con.cursor()
mbligh96cf0512008-04-17 15:25:38 +000082
83
jadmanski0afbb632008-06-06 21:10:57 +000084 def _random_delay(self):
85 delay = random.randint(self.min_delay, self.max_delay)
86 time.sleep(delay)
mbligh65acae52008-04-24 20:21:55 +000087
88
jadmanski0afbb632008-06-06 21:10:57 +000089 def run_with_retry(self, function, *args, **dargs):
90 """Call function(*args, **dargs) until either it passes
91 without an operational error, or a timeout is reached.
92 This will re-connect to the database, so it is NOT safe
93 to use this inside of a database transaction.
jadmanskie7a69092008-05-29 21:03:13 +000094
jadmanski0afbb632008-06-06 21:10:57 +000095 It can be safely used with transactions, but the
96 transaction start & end must be completely contained
97 within the call to 'function'."""
98 OperationalError = _get_error_class("OperationalError")
mbligh65acae52008-04-24 20:21:55 +000099
jadmanski0afbb632008-06-06 21:10:57 +0000100 success = False
101 start_time = time.time()
102 while not success:
103 try:
104 result = function(*args, **dargs)
105 except OperationalError, e:
106 self._log_operational_error(e)
107 stop_time = time.time()
108 elapsed_time = stop_time - start_time
109 if elapsed_time > self.query_timeout:
110 raise
111 else:
112 try:
113 self._random_delay()
114 self._init_db()
115 except OperationalError, e:
116 self._log_operational_error(e)
117 else:
118 success = True
119 return result
mbligh96cf0512008-04-17 15:25:38 +0000120
121
jadmanski0afbb632008-06-06 21:10:57 +0000122 def _log_operational_error(self, e):
mbligh097407d2009-02-17 15:49:37 +0000123 msg = ("%s: An operational error occured during a database "
jadmanski5d4c27e2009-03-02 16:45:42 +0000124 "operation: %s" % (time.strftime("%X %x"), str(e)))
jadmanski0afbb632008-06-06 21:10:57 +0000125 print >> sys.stderr, msg
126 sys.stderr.flush() # we want these msgs to show up immediately
jadmanski60d4fa62008-05-06 22:49:41 +0000127
128
jadmanski0afbb632008-06-06 21:10:57 +0000129 def dprint(self, value):
130 if self.debug:
131 sys.stdout.write('SQL: ' + str(value) + '\n')
mbligh8e1ab172007-09-13 17:29:56 +0000132
mblighd5c33db2006-10-08 21:34:16 +0000133
jadmanski0afbb632008-06-06 21:10:57 +0000134 def commit(self):
135 self.con.commit()
mbligh432bad42007-10-09 19:56:07 +0000136
137
jadmanski0afbb632008-06-06 21:10:57 +0000138 def get_last_autonumber_value(self):
139 self.cur.execute('SELECT LAST_INSERT_ID()', [])
140 return self.cur.fetchall()[0][0]
mblighe12b8612008-02-12 20:58:14 +0000141
142
showardc1a98d12010-01-15 00:22:22 +0000143 def _quote(self, field):
144 return '`%s`' % field
145
146
147 def _where_clause(self, where):
148 if not where:
149 return '', []
150
151 if isinstance(where, dict):
152 # key/value pairs (which should be equal, or None for null)
153 keys, values = [], []
154 for field, value in where.iteritems():
155 quoted_field = self._quote(field)
156 if value is None:
157 keys.append(quoted_field + ' is null')
158 else:
159 keys.append(quoted_field + '=%s')
160 values.append(value)
161 where_clause = ' and '.join(keys)
162 elif isinstance(where, basestring):
163 # the exact string
164 where_clause = where
165 values = []
166 elif isinstance(where, tuple):
167 # preformatted where clause + values
168 where_clause, values = where
169 assert where_clause
170 else:
171 raise ValueError('Invalid "where" value: %r' % where)
172
173 return ' WHERE ' + where_clause, values
174
175
176
177 def select(self, fields, table, where, distinct=False, group_by=None,
178 max_rows=None):
jadmanski0afbb632008-06-06 21:10:57 +0000179 """\
180 This selects all the fields requested from a
181 specific table with a particular where clause.
182 The where clause can either be a dictionary of
183 field=value pairs, a string, or a tuple of (string,
184 a list of values). The last option is what you
185 should use when accepting user input as it'll
186 protect you against sql injection attacks (if
187 all user data is placed in the array rather than
188 the raw SQL).
mbligh12eebfa2008-01-03 02:01:53 +0000189
jadmanski0afbb632008-06-06 21:10:57 +0000190 For example:
191 where = ("a = %s AND b = %s", ['val', 'val'])
192 is better than
193 where = "a = 'val' AND b = 'val'"
194 """
195 cmd = ['select']
196 if distinct:
197 cmd.append('distinct')
198 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +0000199
showardc1a98d12010-01-15 00:22:22 +0000200 where_clause, values = self._where_clause(where)
201 cmd.append(where_clause)
mbligh96cf0512008-04-17 15:25:38 +0000202
jadmanski0afbb632008-06-06 21:10:57 +0000203 if group_by:
204 cmd.append(' GROUP BY ' + group_by)
mbligh83f63a02007-12-12 19:13:04 +0000205
jadmanski0afbb632008-06-06 21:10:57 +0000206 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh96cf0512008-04-17 15:25:38 +0000207
jadmanski0afbb632008-06-06 21:10:57 +0000208 # create a re-runable function for executing the query
209 def exec_sql():
210 sql = ' '.join(cmd)
211 numRec = self.cur.execute(sql, values)
mblighd876f452008-12-03 15:09:17 +0000212 if max_rows is not None and numRec > max_rows:
jadmanski0afbb632008-06-06 21:10:57 +0000213 msg = 'Exceeded allowed number of records'
214 raise MySQLTooManyRows(msg)
215 return self.cur.fetchall()
mbligh96cf0512008-04-17 15:25:38 +0000216
jadmanski0afbb632008-06-06 21:10:57 +0000217 # run the query, re-trying after operational errors
218 if self.autocommit:
219 return self.run_with_retry(exec_sql)
220 else:
221 return exec_sql()
mblighd5c33db2006-10-08 21:34:16 +0000222
mbligh056d0d32006-10-08 22:31:10 +0000223
jadmanski0afbb632008-06-06 21:10:57 +0000224 def select_sql(self, fields, table, sql, values):
225 """\
226 select fields from table "sql"
227 """
228 cmd = 'select %s from %s %s' % (fields, table, sql)
229 self.dprint(cmd)
mbligh414c69e2007-10-05 15:13:06 +0000230
jadmanski0afbb632008-06-06 21:10:57 +0000231 # create a -re-runable function for executing the query
232 def exec_sql():
233 self.cur.execute(cmd, values)
234 return self.cur.fetchall()
mbligh96b9a5a2007-11-24 19:32:20 +0000235
jadmanski0afbb632008-06-06 21:10:57 +0000236 # run the query, re-trying after operational errors
237 if self.autocommit:
238 return self.run_with_retry(exec_sql)
239 else:
240 return exec_sql()
mbligh96b9a5a2007-11-24 19:32:20 +0000241
mbligh608c3252007-08-31 13:53:00 +0000242
jadmanski0afbb632008-06-06 21:10:57 +0000243 def _exec_sql_with_commit(self, sql, values, commit):
244 if self.autocommit:
245 # re-run the query until it succeeds
246 def exec_sql():
247 self.cur.execute(sql, values)
248 self.con.commit()
249 self.run_with_retry(exec_sql)
250 else:
251 # take one shot at running the query
252 self.cur.execute(sql, values)
253 if commit:
254 self.con.commit()
mbligh96b9a5a2007-11-24 19:32:20 +0000255
mbligh2bd48872007-09-20 18:32:25 +0000256
jadmanskib591fba2008-09-10 16:19:22 +0000257 def insert(self, table, data, commit=None):
jadmanski0afbb632008-06-06 21:10:57 +0000258 """\
259 'insert into table (keys) values (%s ... %s)', values
mbligh96cf0512008-04-17 15:25:38 +0000260
jadmanski0afbb632008-06-06 21:10:57 +0000261 data:
262 dictionary of fields and data
263 """
264 fields = data.keys()
265 refs = ['%s' for field in fields]
266 values = [data[field] for field in fields]
showardc1a98d12010-01-15 00:22:22 +0000267 cmd = ('insert into %s (%s) values (%s)' %
268 (table, ','.join(self._quote(field) for field in fields),
269 ','.join(refs)))
jadmanski0afbb632008-06-06 21:10:57 +0000270 self.dprint('%s %s' % (cmd, values))
mblighe9cf9d42007-08-31 08:56:00 +0000271
jadmanski0afbb632008-06-06 21:10:57 +0000272 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000273
mbligh048e1c92007-10-07 00:10:33 +0000274
jadmanski0afbb632008-06-06 21:10:57 +0000275 def delete(self, table, where, commit = None):
276 cmd = ['delete from', table]
mblighd876f452008-12-03 15:09:17 +0000277 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000278 commit = self.autocommit
showardc1a98d12010-01-15 00:22:22 +0000279 where_clause, values = self._where_clause(where)
280 cmd.append(where_clause)
jadmanski0afbb632008-06-06 21:10:57 +0000281 sql = ' '.join(cmd)
282 self.dprint('%s %s' % (sql, values))
mbligh048e1c92007-10-07 00:10:33 +0000283
jadmanski0afbb632008-06-06 21:10:57 +0000284 self._exec_sql_with_commit(sql, values, commit)
mbligh048e1c92007-10-07 00:10:33 +0000285
mbligh7a41a862007-11-30 17:44:24 +0000286
jadmanski0afbb632008-06-06 21:10:57 +0000287 def update(self, table, data, where, commit = None):
288 """\
289 'update table set data values (%s ... %s) where ...'
mbligh2aaeb672007-10-01 14:54:18 +0000290
jadmanski0afbb632008-06-06 21:10:57 +0000291 data:
292 dictionary of fields and data
293 """
mblighd876f452008-12-03 15:09:17 +0000294 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000295 commit = self.autocommit
296 cmd = 'update %s ' % table
297 fields = data.keys()
showardc1a98d12010-01-15 00:22:22 +0000298 data_refs = [self._quote(field) + '=%s' for field in fields]
jadmanski0afbb632008-06-06 21:10:57 +0000299 data_values = [data[field] for field in fields]
jadmanski74eebf32008-07-15 20:04:42 +0000300 cmd += ' set ' + ', '.join(data_refs)
mbligh2aaeb672007-10-01 14:54:18 +0000301
showardc1a98d12010-01-15 00:22:22 +0000302 where_clause, where_values = self._where_clause(where)
303 cmd += where_clause
mbligh2aaeb672007-10-01 14:54:18 +0000304
jadmanski0afbb632008-06-06 21:10:57 +0000305 values = data_values + where_values
jadmanski74eebf32008-07-15 20:04:42 +0000306 self.dprint('%s %s' % (cmd, values))
mbligh2aaeb672007-10-01 14:54:18 +0000307
jadmanski0afbb632008-06-06 21:10:57 +0000308 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000309
310
jadmanski0afbb632008-06-06 21:10:57 +0000311 def delete_job(self, tag, commit = None):
312 job_idx = self.find_job(tag)
313 for test_idx in self.find_tests(job_idx):
314 where = {'test_idx' : test_idx}
showardeab66ce2009-12-23 00:03:56 +0000315 self.delete('tko_iteration_result', where)
316 self.delete('tko_iteration_attributes', where)
317 self.delete('tko_test_attributes', where)
318 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000319 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000320 self.delete('tko_tests', where)
321 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000322
apw7a7316b2008-02-21 17:42:05 +0000323
jadmanski0afbb632008-06-06 21:10:57 +0000324 def insert_job(self, tag, job, commit = None):
325 job.machine_idx = self.lookup_machine(job.machine)
326 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000327 job.machine_idx = self.insert_machine(job, commit=commit)
328 else:
329 self.update_machine_information(job, commit=commit)
330
jamesrena12b8a02010-06-16 23:28:23 +0000331 afe_job_id = utils.get_afe_job_id(tag)
showardc1c1caf2009-09-08 16:26:50 +0000332
showard0fec8a02009-12-04 01:19:54 +0000333 data = {'tag':tag,
334 'label': job.label,
335 'username': job.user,
336 'machine_idx': job.machine_idx,
337 'queued_time': job.queued_time,
338 'started_time': job.started_time,
339 'finished_time': job.finished_time,
340 'afe_job_id': afe_job_id}
341 is_update = hasattr(job, 'index')
342 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000343 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000344 else:
showardeab66ce2009-12-23 00:03:56 +0000345 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000346 job.index = self.get_last_autonumber_value()
showardc1a98d12010-01-15 00:22:22 +0000347 self.update_job_keyvals(job, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000348 for test in job.tests:
349 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000350
mbligh237bed32007-09-05 13:05:57 +0000351
showardc1a98d12010-01-15 00:22:22 +0000352 def update_job_keyvals(self, job, commit=None):
353 for key, value in job.keyval_dict.iteritems():
354 where = {'job_id': job.index, 'key': key}
355 data = dict(where, value=value)
356 exists = self.select('id', 'tko_job_keyvals', where=where)
357
358 if exists:
359 self.update('tko_job_keyvals', data, where=where, commit=commit)
360 else:
361 self.insert('tko_job_keyvals', data, commit=commit)
362
363
jadmanski0afbb632008-06-06 21:10:57 +0000364 def insert_test(self, job, test, commit = None):
365 kver = self.insert_kernel(test.kernel, commit=commit)
366 data = {'job_idx':job.index, 'test':test.testname,
367 'subdir':test.subdir, 'kernel_idx':kver,
368 'status':self.status_idx[test.status],
369 'reason':test.reason, 'machine_idx':job.machine_idx,
370 'started_time': test.started_time,
371 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000372 is_update = hasattr(test, "test_idx")
373 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000374 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000375 self.update('tko_tests', data,
376 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000377 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000378 self.delete('tko_iteration_result', where)
379 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000380 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000381 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000382 else:
showardeab66ce2009-12-23 00:03:56 +0000383 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000384 test_idx = test.test_idx = self.get_last_autonumber_value()
385 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000386
jadmanski0afbb632008-06-06 21:10:57 +0000387 for i in test.iterations:
388 data['iteration'] = i.index
389 for key, value in i.attr_keyval.iteritems():
390 data['attribute'] = key
391 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000392 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000393 commit=commit)
394 for key, value in i.perf_keyval.iteritems():
395 data['attribute'] = key
396 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000397 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000398 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000399
jadmanski0afbb632008-06-06 21:10:57 +0000400 for key, value in test.attributes.iteritems():
401 data = {'test_idx': test_idx, 'attribute': key,
402 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000403 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000404
jadmanski9b6babf2009-04-21 17:57:40 +0000405 if not is_update:
406 for label_index in test.labels:
407 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000408 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000409
mbligh056d0d32006-10-08 22:31:10 +0000410
jadmanski0afbb632008-06-06 21:10:57 +0000411 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000412 if self.machine_group or not self.machine_map:
413 return
jadmanski0afbb632008-06-06 21:10:57 +0000414 for line in open(self.machine_map, 'r').readlines():
415 (machine, group) = line.split()
416 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000417
418
showard71b94312009-08-20 23:40:02 +0000419 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000420 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000421 group = job.machine_group
422 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000423
424 if not group:
showard71b94312009-08-20 23:40:02 +0000425 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000426 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000427 if group == hostname and owner:
428 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000429
showard71b94312009-08-20 23:40:02 +0000430 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
431
432
433 def insert_machine(self, job, commit = None):
434 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000435 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000436 return self.get_last_autonumber_value()
437
438
showard71b94312009-08-20 23:40:02 +0000439 def update_machine_information(self, job, commit = None):
440 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000441 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000442 where={'hostname': machine_info['hostname']},
443 commit=commit)
444
445
jadmanski0afbb632008-06-06 21:10:57 +0000446 def lookup_machine(self, hostname):
447 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000448 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000449 if rows:
450 return rows[0][0]
451 else:
452 return None
453
454
455 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000456 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000457 {'kernel_hash':kernel.kernel_hash})
458 if rows:
459 return rows[0][0]
460 else:
461 return None
462
463
464 def insert_kernel(self, kernel, commit = None):
465 kver = self.lookup_kernel(kernel)
466 if kver:
467 return kver
468
469 # If this kernel has any significant patches, append their hash
470 # as diferentiator.
471 printable = kernel.base
472 patch_count = 0
473 for patch in kernel.patches:
474 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
475 patch.reference)
476 if not match:
477 patch_count += 1
478
showardeab66ce2009-12-23 00:03:56 +0000479 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000480 {'base':kernel.base,
481 'kernel_hash':kernel.kernel_hash,
482 'printable':printable},
483 commit=commit)
484 kver = self.get_last_autonumber_value()
485
486 if patch_count > 0:
487 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000488 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000489 {'printable':printable},
490 {'kernel_idx':kver})
491
492 for patch in kernel.patches:
493 self.insert_patch(kver, patch, commit=commit)
494 return kver
495
496
497 def insert_patch(self, kver, patch, commit = None):
498 print patch.reference
499 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000500 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000501 {'kernel_idx': kver,
502 'name':name,
503 'url':patch.reference,
504 'hash':patch.hash},
505 commit=commit)
506
507
jadmanski74eebf32008-07-15 20:04:42 +0000508 def find_test(self, job_idx, testname, subdir):
509 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000510 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000511 if rows:
512 return rows[0][0]
513 else:
514 return None
515
516
517 def find_tests(self, job_idx):
518 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000519 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000520 if rows:
521 return [row[0] for row in rows]
522 else:
523 return []
524
525
526 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000527 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000528 if rows:
529 return rows[0][0]
530 else:
531 return None
mblighaf25f062007-12-03 17:48:35 +0000532
533
mbligh96cf0512008-04-17 15:25:38 +0000534def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000535 """Get the database type name to use from the global config."""
536 get_value = global_config.global_config.get_config_value
showard250d84d2010-01-12 21:59:48 +0000537 return "db_" + get_value("AUTOTEST_WEB", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000538
mbligh96cf0512008-04-17 15:25:38 +0000539
540def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000541 """Retrieves the appropriate error class by name from the database
542 module."""
543 db_module = __import__("autotest_lib.tko." + _get_db_type(),
544 globals(), locals(), ["driver"])
545 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000546
547
548def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000549 """Creates an instance of the database class with the arguments
550 provided in args and dargs, using the database type specified by
551 the global configuration (defaulting to mysql)."""
552 db_type = _get_db_type()
553 db_module = __import__("autotest_lib.tko." + db_type, globals(),
554 locals(), [db_type])
555 db = getattr(db_module, db_type)(*args, **dargs)
556 return db