blob: 6a2eb1332a719724d7358d55544c50b5b8a7570a [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
Simran Basie129a962012-08-31 13:03:53 -0700138 def rollback(self):
139 self.con.rollback()
140
141
jadmanski0afbb632008-06-06 21:10:57 +0000142 def get_last_autonumber_value(self):
143 self.cur.execute('SELECT LAST_INSERT_ID()', [])
144 return self.cur.fetchall()[0][0]
mblighe12b8612008-02-12 20:58:14 +0000145
146
showardc1a98d12010-01-15 00:22:22 +0000147 def _quote(self, field):
148 return '`%s`' % field
149
150
151 def _where_clause(self, where):
152 if not where:
153 return '', []
154
155 if isinstance(where, dict):
156 # key/value pairs (which should be equal, or None for null)
157 keys, values = [], []
158 for field, value in where.iteritems():
159 quoted_field = self._quote(field)
160 if value is None:
161 keys.append(quoted_field + ' is null')
162 else:
163 keys.append(quoted_field + '=%s')
164 values.append(value)
165 where_clause = ' and '.join(keys)
166 elif isinstance(where, basestring):
167 # the exact string
168 where_clause = where
169 values = []
170 elif isinstance(where, tuple):
171 # preformatted where clause + values
172 where_clause, values = where
173 assert where_clause
174 else:
175 raise ValueError('Invalid "where" value: %r' % where)
176
177 return ' WHERE ' + where_clause, values
178
179
180
181 def select(self, fields, table, where, distinct=False, group_by=None,
182 max_rows=None):
jadmanski0afbb632008-06-06 21:10:57 +0000183 """\
184 This selects all the fields requested from a
185 specific table with a particular where clause.
186 The where clause can either be a dictionary of
187 field=value pairs, a string, or a tuple of (string,
188 a list of values). The last option is what you
189 should use when accepting user input as it'll
190 protect you against sql injection attacks (if
191 all user data is placed in the array rather than
192 the raw SQL).
mbligh12eebfa2008-01-03 02:01:53 +0000193
jadmanski0afbb632008-06-06 21:10:57 +0000194 For example:
195 where = ("a = %s AND b = %s", ['val', 'val'])
196 is better than
197 where = "a = 'val' AND b = 'val'"
198 """
199 cmd = ['select']
200 if distinct:
201 cmd.append('distinct')
202 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +0000203
showardc1a98d12010-01-15 00:22:22 +0000204 where_clause, values = self._where_clause(where)
205 cmd.append(where_clause)
mbligh96cf0512008-04-17 15:25:38 +0000206
jadmanski0afbb632008-06-06 21:10:57 +0000207 if group_by:
208 cmd.append(' GROUP BY ' + group_by)
mbligh83f63a02007-12-12 19:13:04 +0000209
jadmanski0afbb632008-06-06 21:10:57 +0000210 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh96cf0512008-04-17 15:25:38 +0000211
jadmanski0afbb632008-06-06 21:10:57 +0000212 # create a re-runable function for executing the query
213 def exec_sql():
214 sql = ' '.join(cmd)
215 numRec = self.cur.execute(sql, values)
mblighd876f452008-12-03 15:09:17 +0000216 if max_rows is not None and numRec > max_rows:
jadmanski0afbb632008-06-06 21:10:57 +0000217 msg = 'Exceeded allowed number of records'
218 raise MySQLTooManyRows(msg)
219 return self.cur.fetchall()
mbligh96cf0512008-04-17 15:25:38 +0000220
jadmanski0afbb632008-06-06 21:10:57 +0000221 # run the query, re-trying after operational errors
222 if self.autocommit:
223 return self.run_with_retry(exec_sql)
224 else:
225 return exec_sql()
mblighd5c33db2006-10-08 21:34:16 +0000226
mbligh056d0d32006-10-08 22:31:10 +0000227
jadmanski0afbb632008-06-06 21:10:57 +0000228 def select_sql(self, fields, table, sql, values):
229 """\
230 select fields from table "sql"
231 """
232 cmd = 'select %s from %s %s' % (fields, table, sql)
233 self.dprint(cmd)
mbligh414c69e2007-10-05 15:13:06 +0000234
jadmanski0afbb632008-06-06 21:10:57 +0000235 # create a -re-runable function for executing the query
236 def exec_sql():
237 self.cur.execute(cmd, values)
238 return self.cur.fetchall()
mbligh96b9a5a2007-11-24 19:32:20 +0000239
jadmanski0afbb632008-06-06 21:10:57 +0000240 # run the query, re-trying after operational errors
241 if self.autocommit:
242 return self.run_with_retry(exec_sql)
243 else:
244 return exec_sql()
mbligh96b9a5a2007-11-24 19:32:20 +0000245
mbligh608c3252007-08-31 13:53:00 +0000246
jadmanski0afbb632008-06-06 21:10:57 +0000247 def _exec_sql_with_commit(self, sql, values, commit):
248 if self.autocommit:
249 # re-run the query until it succeeds
250 def exec_sql():
251 self.cur.execute(sql, values)
252 self.con.commit()
253 self.run_with_retry(exec_sql)
254 else:
255 # take one shot at running the query
256 self.cur.execute(sql, values)
257 if commit:
258 self.con.commit()
mbligh96b9a5a2007-11-24 19:32:20 +0000259
mbligh2bd48872007-09-20 18:32:25 +0000260
jadmanskib591fba2008-09-10 16:19:22 +0000261 def insert(self, table, data, commit=None):
jadmanski0afbb632008-06-06 21:10:57 +0000262 """\
263 'insert into table (keys) values (%s ... %s)', values
mbligh96cf0512008-04-17 15:25:38 +0000264
jadmanski0afbb632008-06-06 21:10:57 +0000265 data:
266 dictionary of fields and data
267 """
268 fields = data.keys()
269 refs = ['%s' for field in fields]
270 values = [data[field] for field in fields]
showardc1a98d12010-01-15 00:22:22 +0000271 cmd = ('insert into %s (%s) values (%s)' %
272 (table, ','.join(self._quote(field) for field in fields),
273 ','.join(refs)))
jadmanski0afbb632008-06-06 21:10:57 +0000274 self.dprint('%s %s' % (cmd, values))
mblighe9cf9d42007-08-31 08:56:00 +0000275
jadmanski0afbb632008-06-06 21:10:57 +0000276 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000277
mbligh048e1c92007-10-07 00:10:33 +0000278
jadmanski0afbb632008-06-06 21:10:57 +0000279 def delete(self, table, where, commit = None):
280 cmd = ['delete from', table]
mblighd876f452008-12-03 15:09:17 +0000281 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000282 commit = self.autocommit
showardc1a98d12010-01-15 00:22:22 +0000283 where_clause, values = self._where_clause(where)
284 cmd.append(where_clause)
jadmanski0afbb632008-06-06 21:10:57 +0000285 sql = ' '.join(cmd)
286 self.dprint('%s %s' % (sql, values))
mbligh048e1c92007-10-07 00:10:33 +0000287
jadmanski0afbb632008-06-06 21:10:57 +0000288 self._exec_sql_with_commit(sql, values, commit)
mbligh048e1c92007-10-07 00:10:33 +0000289
mbligh7a41a862007-11-30 17:44:24 +0000290
jadmanski0afbb632008-06-06 21:10:57 +0000291 def update(self, table, data, where, commit = None):
292 """\
293 'update table set data values (%s ... %s) where ...'
mbligh2aaeb672007-10-01 14:54:18 +0000294
jadmanski0afbb632008-06-06 21:10:57 +0000295 data:
296 dictionary of fields and data
297 """
mblighd876f452008-12-03 15:09:17 +0000298 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000299 commit = self.autocommit
300 cmd = 'update %s ' % table
301 fields = data.keys()
showardc1a98d12010-01-15 00:22:22 +0000302 data_refs = [self._quote(field) + '=%s' for field in fields]
jadmanski0afbb632008-06-06 21:10:57 +0000303 data_values = [data[field] for field in fields]
jadmanski74eebf32008-07-15 20:04:42 +0000304 cmd += ' set ' + ', '.join(data_refs)
mbligh2aaeb672007-10-01 14:54:18 +0000305
showardc1a98d12010-01-15 00:22:22 +0000306 where_clause, where_values = self._where_clause(where)
307 cmd += where_clause
mbligh2aaeb672007-10-01 14:54:18 +0000308
jadmanski0afbb632008-06-06 21:10:57 +0000309 values = data_values + where_values
jadmanski74eebf32008-07-15 20:04:42 +0000310 self.dprint('%s %s' % (cmd, values))
mbligh2aaeb672007-10-01 14:54:18 +0000311
jadmanski0afbb632008-06-06 21:10:57 +0000312 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000313
314
jadmanski0afbb632008-06-06 21:10:57 +0000315 def delete_job(self, tag, commit = None):
316 job_idx = self.find_job(tag)
317 for test_idx in self.find_tests(job_idx):
318 where = {'test_idx' : test_idx}
showardeab66ce2009-12-23 00:03:56 +0000319 self.delete('tko_iteration_result', where)
320 self.delete('tko_iteration_attributes', where)
321 self.delete('tko_test_attributes', where)
322 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000323 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000324 self.delete('tko_tests', where)
325 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000326
apw7a7316b2008-02-21 17:42:05 +0000327
jadmanski0afbb632008-06-06 21:10:57 +0000328 def insert_job(self, tag, job, commit = None):
329 job.machine_idx = self.lookup_machine(job.machine)
330 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000331 job.machine_idx = self.insert_machine(job, commit=commit)
332 else:
333 self.update_machine_information(job, commit=commit)
334
jamesrena12b8a02010-06-16 23:28:23 +0000335 afe_job_id = utils.get_afe_job_id(tag)
showardc1c1caf2009-09-08 16:26:50 +0000336
showard0fec8a02009-12-04 01:19:54 +0000337 data = {'tag':tag,
338 'label': job.label,
339 'username': job.user,
340 'machine_idx': job.machine_idx,
341 'queued_time': job.queued_time,
342 'started_time': job.started_time,
343 'finished_time': job.finished_time,
344 'afe_job_id': afe_job_id}
345 is_update = hasattr(job, 'index')
346 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000347 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000348 else:
showardeab66ce2009-12-23 00:03:56 +0000349 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000350 job.index = self.get_last_autonumber_value()
showardc1a98d12010-01-15 00:22:22 +0000351 self.update_job_keyvals(job, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000352 for test in job.tests:
353 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000354
mbligh237bed32007-09-05 13:05:57 +0000355
showardc1a98d12010-01-15 00:22:22 +0000356 def update_job_keyvals(self, job, commit=None):
357 for key, value in job.keyval_dict.iteritems():
358 where = {'job_id': job.index, 'key': key}
359 data = dict(where, value=value)
360 exists = self.select('id', 'tko_job_keyvals', where=where)
361
362 if exists:
363 self.update('tko_job_keyvals', data, where=where, commit=commit)
364 else:
365 self.insert('tko_job_keyvals', data, commit=commit)
366
367
jadmanski0afbb632008-06-06 21:10:57 +0000368 def insert_test(self, job, test, commit = None):
369 kver = self.insert_kernel(test.kernel, commit=commit)
370 data = {'job_idx':job.index, 'test':test.testname,
371 'subdir':test.subdir, 'kernel_idx':kver,
372 'status':self.status_idx[test.status],
373 'reason':test.reason, 'machine_idx':job.machine_idx,
374 'started_time': test.started_time,
375 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000376 is_update = hasattr(test, "test_idx")
377 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000378 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000379 self.update('tko_tests', data,
380 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000381 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000382 self.delete('tko_iteration_result', where)
383 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000384 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000385 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000386 else:
showardeab66ce2009-12-23 00:03:56 +0000387 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000388 test_idx = test.test_idx = self.get_last_autonumber_value()
389 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000390
jadmanski0afbb632008-06-06 21:10:57 +0000391 for i in test.iterations:
392 data['iteration'] = i.index
393 for key, value in i.attr_keyval.iteritems():
394 data['attribute'] = key
395 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000396 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000397 commit=commit)
398 for key, value in i.perf_keyval.iteritems():
399 data['attribute'] = key
400 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000401 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000402 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000403
jadmanski0afbb632008-06-06 21:10:57 +0000404 for key, value in test.attributes.iteritems():
405 data = {'test_idx': test_idx, 'attribute': key,
406 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000407 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000408
jadmanski9b6babf2009-04-21 17:57:40 +0000409 if not is_update:
410 for label_index in test.labels:
411 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000412 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000413
mbligh056d0d32006-10-08 22:31:10 +0000414
jadmanski0afbb632008-06-06 21:10:57 +0000415 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000416 if self.machine_group or not self.machine_map:
417 return
jadmanski0afbb632008-06-06 21:10:57 +0000418 for line in open(self.machine_map, 'r').readlines():
419 (machine, group) = line.split()
420 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000421
422
showard71b94312009-08-20 23:40:02 +0000423 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000424 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000425 group = job.machine_group
426 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000427
428 if not group:
showard71b94312009-08-20 23:40:02 +0000429 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000430 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000431 if group == hostname and owner:
432 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000433
showard71b94312009-08-20 23:40:02 +0000434 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
435
436
437 def insert_machine(self, job, commit = None):
438 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000439 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000440 return self.get_last_autonumber_value()
441
442
showard71b94312009-08-20 23:40:02 +0000443 def update_machine_information(self, job, commit = None):
444 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000445 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000446 where={'hostname': machine_info['hostname']},
447 commit=commit)
448
449
jadmanski0afbb632008-06-06 21:10:57 +0000450 def lookup_machine(self, hostname):
451 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000452 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000453 if rows:
454 return rows[0][0]
455 else:
456 return None
457
458
459 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000460 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000461 {'kernel_hash':kernel.kernel_hash})
462 if rows:
463 return rows[0][0]
464 else:
465 return None
466
467
468 def insert_kernel(self, kernel, commit = None):
469 kver = self.lookup_kernel(kernel)
470 if kver:
471 return kver
472
473 # If this kernel has any significant patches, append their hash
474 # as diferentiator.
475 printable = kernel.base
476 patch_count = 0
477 for patch in kernel.patches:
478 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
479 patch.reference)
480 if not match:
481 patch_count += 1
482
showardeab66ce2009-12-23 00:03:56 +0000483 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000484 {'base':kernel.base,
485 'kernel_hash':kernel.kernel_hash,
486 'printable':printable},
487 commit=commit)
488 kver = self.get_last_autonumber_value()
489
490 if patch_count > 0:
491 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000492 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000493 {'printable':printable},
494 {'kernel_idx':kver})
495
496 for patch in kernel.patches:
497 self.insert_patch(kver, patch, commit=commit)
498 return kver
499
500
501 def insert_patch(self, kver, patch, commit = None):
502 print patch.reference
503 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000504 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000505 {'kernel_idx': kver,
506 'name':name,
507 'url':patch.reference,
508 'hash':patch.hash},
509 commit=commit)
510
511
jadmanski74eebf32008-07-15 20:04:42 +0000512 def find_test(self, job_idx, testname, subdir):
513 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000514 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000515 if rows:
516 return rows[0][0]
517 else:
518 return None
519
520
521 def find_tests(self, job_idx):
522 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000523 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000524 if rows:
525 return [row[0] for row in rows]
526 else:
527 return []
528
529
530 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000531 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000532 if rows:
533 return rows[0][0]
534 else:
535 return None
mblighaf25f062007-12-03 17:48:35 +0000536
537
mbligh96cf0512008-04-17 15:25:38 +0000538def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000539 """Get the database type name to use from the global config."""
540 get_value = global_config.global_config.get_config_value
showard250d84d2010-01-12 21:59:48 +0000541 return "db_" + get_value("AUTOTEST_WEB", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000542
mbligh96cf0512008-04-17 15:25:38 +0000543
544def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000545 """Retrieves the appropriate error class by name from the database
546 module."""
547 db_module = __import__("autotest_lib.tko." + _get_db_type(),
548 globals(), locals(), ["driver"])
549 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000550
551
552def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000553 """Creates an instance of the database class with the arguments
554 provided in args and dargs, using the database type specified by
555 the global configuration (defaulting to mysql)."""
556 db_type = _get_db_type()
557 db_module = __import__("autotest_lib.tko." + db_type, globals(),
558 locals(), [db_type])
559 db = getattr(db_module, db_type)(*args, **dargs)
560 return db