blob: 9b9f456d4fcdd155dab18e5c27588897c8ad01d5 [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
5
mblighed4d6dd2008-02-27 16:49:43 +00006
mblighaea09602008-04-16 22:59:37 +00007class MySQLTooManyRows(Exception):
jadmanski0afbb632008-06-06 21:10:57 +00008 pass
mblighaea09602008-04-16 22:59:37 +00009
mblighd5c33db2006-10-08 21:34:16 +000010
mbligh7636b3a2008-06-11 15:44:01 +000011class db_sql(object):
jadmanski0afbb632008-06-06 21:10:57 +000012 def __init__(self, debug=False, autocommit=True, host=None,
13 database=None, user=None, password=None):
14 self.debug = debug
15 self.autocommit = autocommit
16 self._load_config(host, database, user, password)
mbligh96cf0512008-04-17 15:25:38 +000017
jadmanski0afbb632008-06-06 21:10:57 +000018 self.con = None
19 self._init_db()
mblighd5c33db2006-10-08 21:34:16 +000020
jadmanski0afbb632008-06-06 21:10:57 +000021 # if not present, insert statuses
22 self.status_idx = {}
23 self.status_word = {}
showardeab66ce2009-12-23 00:03:56 +000024 status_rows = self.select('status_idx, word', 'tko_status', None)
jadmanski0afbb632008-06-06 21:10:57 +000025 for s in status_rows:
26 self.status_idx[s[1]] = s[0]
27 self.status_word[s[0]] = s[1]
mbligh048e1c92007-10-07 00:10:33 +000028
jadmanski0afbb632008-06-06 21:10:57 +000029 machine_map = os.path.join(os.path.dirname(__file__),
30 'machines')
31 if os.path.exists(machine_map):
32 self.machine_map = machine_map
33 else:
34 self.machine_map = None
35 self.machine_group = {}
mbligh048e1c92007-10-07 00:10:33 +000036
mbligh8e1ab172007-09-13 17:29:56 +000037
jadmanski0afbb632008-06-06 21:10:57 +000038 def _load_config(self, host, database, user, password):
39 # grab the global config
40 get_value = global_config.global_config.get_config_value
mbligh65acae52008-04-24 20:21:55 +000041
jadmanski0afbb632008-06-06 21:10:57 +000042 # grab the host, database
43 if host:
44 self.host = host
45 else:
showard250d84d2010-01-12 21:59:48 +000046 self.host = get_value("AUTOTEST_WEB", "host")
jadmanski0afbb632008-06-06 21:10:57 +000047 if database:
48 self.database = database
49 else:
showard250d84d2010-01-12 21:59:48 +000050 self.database = get_value("AUTOTEST_WEB", "database")
mbligh65acae52008-04-24 20:21:55 +000051
jadmanski0afbb632008-06-06 21:10:57 +000052 # grab the user and password
53 if user:
54 self.user = user
55 else:
showard250d84d2010-01-12 21:59:48 +000056 self.user = get_value("AUTOTEST_WEB", "user")
mblighdc2c9bb2008-12-22 14:47:35 +000057 if password is not None:
jadmanski0afbb632008-06-06 21:10:57 +000058 self.password = password
59 else:
showard250d84d2010-01-12 21:59:48 +000060 self.password = get_value("AUTOTEST_WEB", "password")
mbligh65acae52008-04-24 20:21:55 +000061
jadmanski0afbb632008-06-06 21:10:57 +000062 # grab the timeout configuration
showard250d84d2010-01-12 21:59:48 +000063 self.query_timeout = get_value("AUTOTEST_WEB", "query_timeout",
jadmanski0afbb632008-06-06 21:10:57 +000064 type=int, default=3600)
showard250d84d2010-01-12 21:59:48 +000065 self.min_delay = get_value("AUTOTEST_WEB", "min_retry_delay", type=int,
jadmanski0afbb632008-06-06 21:10:57 +000066 default=20)
showard250d84d2010-01-12 21:59:48 +000067 self.max_delay = get_value("AUTOTEST_WEB", "max_retry_delay", type=int,
jadmanski0afbb632008-06-06 21:10:57 +000068 default=60)
mbligh65acae52008-04-24 20:21:55 +000069
70
jadmanski0afbb632008-06-06 21:10:57 +000071 def _init_db(self):
72 # make sure we clean up any existing connection
73 if self.con:
74 self.con.close()
75 self.con = None
mbligh65acae52008-04-24 20:21:55 +000076
jadmanski0afbb632008-06-06 21:10:57 +000077 # create the db connection and cursor
78 self.con = self.connect(self.host, self.database,
79 self.user, self.password)
80 self.cur = self.con.cursor()
mbligh96cf0512008-04-17 15:25:38 +000081
82
jadmanski0afbb632008-06-06 21:10:57 +000083 def _random_delay(self):
84 delay = random.randint(self.min_delay, self.max_delay)
85 time.sleep(delay)
mbligh65acae52008-04-24 20:21:55 +000086
87
jadmanski0afbb632008-06-06 21:10:57 +000088 def run_with_retry(self, function, *args, **dargs):
89 """Call function(*args, **dargs) until either it passes
90 without an operational error, or a timeout is reached.
91 This will re-connect to the database, so it is NOT safe
92 to use this inside of a database transaction.
jadmanskie7a69092008-05-29 21:03:13 +000093
jadmanski0afbb632008-06-06 21:10:57 +000094 It can be safely used with transactions, but the
95 transaction start & end must be completely contained
96 within the call to 'function'."""
97 OperationalError = _get_error_class("OperationalError")
mbligh65acae52008-04-24 20:21:55 +000098
jadmanski0afbb632008-06-06 21:10:57 +000099 success = False
100 start_time = time.time()
101 while not success:
102 try:
103 result = function(*args, **dargs)
104 except OperationalError, e:
105 self._log_operational_error(e)
106 stop_time = time.time()
107 elapsed_time = stop_time - start_time
108 if elapsed_time > self.query_timeout:
109 raise
110 else:
111 try:
112 self._random_delay()
113 self._init_db()
114 except OperationalError, e:
115 self._log_operational_error(e)
116 else:
117 success = True
118 return result
mbligh96cf0512008-04-17 15:25:38 +0000119
120
jadmanski0afbb632008-06-06 21:10:57 +0000121 def _log_operational_error(self, e):
mbligh097407d2009-02-17 15:49:37 +0000122 msg = ("%s: An operational error occured during a database "
jadmanski5d4c27e2009-03-02 16:45:42 +0000123 "operation: %s" % (time.strftime("%X %x"), str(e)))
jadmanski0afbb632008-06-06 21:10:57 +0000124 print >> sys.stderr, msg
125 sys.stderr.flush() # we want these msgs to show up immediately
jadmanski60d4fa62008-05-06 22:49:41 +0000126
127
jadmanski0afbb632008-06-06 21:10:57 +0000128 def dprint(self, value):
129 if self.debug:
130 sys.stdout.write('SQL: ' + str(value) + '\n')
mbligh8e1ab172007-09-13 17:29:56 +0000131
mblighd5c33db2006-10-08 21:34:16 +0000132
jadmanski0afbb632008-06-06 21:10:57 +0000133 def commit(self):
134 self.con.commit()
mbligh432bad42007-10-09 19:56:07 +0000135
136
jadmanski0afbb632008-06-06 21:10:57 +0000137 def get_last_autonumber_value(self):
138 self.cur.execute('SELECT LAST_INSERT_ID()', [])
139 return self.cur.fetchall()[0][0]
mblighe12b8612008-02-12 20:58:14 +0000140
141
showardc1a98d12010-01-15 00:22:22 +0000142 def _quote(self, field):
143 return '`%s`' % field
144
145
146 def _where_clause(self, where):
147 if not where:
148 return '', []
149
150 if isinstance(where, dict):
151 # key/value pairs (which should be equal, or None for null)
152 keys, values = [], []
153 for field, value in where.iteritems():
154 quoted_field = self._quote(field)
155 if value is None:
156 keys.append(quoted_field + ' is null')
157 else:
158 keys.append(quoted_field + '=%s')
159 values.append(value)
160 where_clause = ' and '.join(keys)
161 elif isinstance(where, basestring):
162 # the exact string
163 where_clause = where
164 values = []
165 elif isinstance(where, tuple):
166 # preformatted where clause + values
167 where_clause, values = where
168 assert where_clause
169 else:
170 raise ValueError('Invalid "where" value: %r' % where)
171
172 return ' WHERE ' + where_clause, values
173
174
175
176 def select(self, fields, table, where, distinct=False, group_by=None,
177 max_rows=None):
jadmanski0afbb632008-06-06 21:10:57 +0000178 """\
179 This selects all the fields requested from a
180 specific table with a particular where clause.
181 The where clause can either be a dictionary of
182 field=value pairs, a string, or a tuple of (string,
183 a list of values). The last option is what you
184 should use when accepting user input as it'll
185 protect you against sql injection attacks (if
186 all user data is placed in the array rather than
187 the raw SQL).
mbligh12eebfa2008-01-03 02:01:53 +0000188
jadmanski0afbb632008-06-06 21:10:57 +0000189 For example:
190 where = ("a = %s AND b = %s", ['val', 'val'])
191 is better than
192 where = "a = 'val' AND b = 'val'"
193 """
194 cmd = ['select']
195 if distinct:
196 cmd.append('distinct')
197 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +0000198
showardc1a98d12010-01-15 00:22:22 +0000199 where_clause, values = self._where_clause(where)
200 cmd.append(where_clause)
mbligh96cf0512008-04-17 15:25:38 +0000201
jadmanski0afbb632008-06-06 21:10:57 +0000202 if group_by:
203 cmd.append(' GROUP BY ' + group_by)
mbligh83f63a02007-12-12 19:13:04 +0000204
jadmanski0afbb632008-06-06 21:10:57 +0000205 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh96cf0512008-04-17 15:25:38 +0000206
jadmanski0afbb632008-06-06 21:10:57 +0000207 # create a re-runable function for executing the query
208 def exec_sql():
209 sql = ' '.join(cmd)
210 numRec = self.cur.execute(sql, values)
mblighd876f452008-12-03 15:09:17 +0000211 if max_rows is not None and numRec > max_rows:
jadmanski0afbb632008-06-06 21:10:57 +0000212 msg = 'Exceeded allowed number of records'
213 raise MySQLTooManyRows(msg)
214 return self.cur.fetchall()
mbligh96cf0512008-04-17 15:25:38 +0000215
jadmanski0afbb632008-06-06 21:10:57 +0000216 # run the query, re-trying after operational errors
217 if self.autocommit:
218 return self.run_with_retry(exec_sql)
219 else:
220 return exec_sql()
mblighd5c33db2006-10-08 21:34:16 +0000221
mbligh056d0d32006-10-08 22:31:10 +0000222
jadmanski0afbb632008-06-06 21:10:57 +0000223 def select_sql(self, fields, table, sql, values):
224 """\
225 select fields from table "sql"
226 """
227 cmd = 'select %s from %s %s' % (fields, table, sql)
228 self.dprint(cmd)
mbligh414c69e2007-10-05 15:13:06 +0000229
jadmanski0afbb632008-06-06 21:10:57 +0000230 # create a -re-runable function for executing the query
231 def exec_sql():
232 self.cur.execute(cmd, values)
233 return self.cur.fetchall()
mbligh96b9a5a2007-11-24 19:32:20 +0000234
jadmanski0afbb632008-06-06 21:10:57 +0000235 # run the query, re-trying after operational errors
236 if self.autocommit:
237 return self.run_with_retry(exec_sql)
238 else:
239 return exec_sql()
mbligh96b9a5a2007-11-24 19:32:20 +0000240
mbligh608c3252007-08-31 13:53:00 +0000241
jadmanski0afbb632008-06-06 21:10:57 +0000242 def _exec_sql_with_commit(self, sql, values, commit):
243 if self.autocommit:
244 # re-run the query until it succeeds
245 def exec_sql():
246 self.cur.execute(sql, values)
247 self.con.commit()
248 self.run_with_retry(exec_sql)
249 else:
250 # take one shot at running the query
251 self.cur.execute(sql, values)
252 if commit:
253 self.con.commit()
mbligh96b9a5a2007-11-24 19:32:20 +0000254
mbligh2bd48872007-09-20 18:32:25 +0000255
jadmanskib591fba2008-09-10 16:19:22 +0000256 def insert(self, table, data, commit=None):
jadmanski0afbb632008-06-06 21:10:57 +0000257 """\
258 'insert into table (keys) values (%s ... %s)', values
mbligh96cf0512008-04-17 15:25:38 +0000259
jadmanski0afbb632008-06-06 21:10:57 +0000260 data:
261 dictionary of fields and data
262 """
263 fields = data.keys()
264 refs = ['%s' for field in fields]
265 values = [data[field] for field in fields]
showardc1a98d12010-01-15 00:22:22 +0000266 cmd = ('insert into %s (%s) values (%s)' %
267 (table, ','.join(self._quote(field) for field in fields),
268 ','.join(refs)))
jadmanski0afbb632008-06-06 21:10:57 +0000269 self.dprint('%s %s' % (cmd, values))
mblighe9cf9d42007-08-31 08:56:00 +0000270
jadmanski0afbb632008-06-06 21:10:57 +0000271 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000272
mbligh048e1c92007-10-07 00:10:33 +0000273
jadmanski0afbb632008-06-06 21:10:57 +0000274 def delete(self, table, where, commit = None):
275 cmd = ['delete from', table]
mblighd876f452008-12-03 15:09:17 +0000276 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000277 commit = self.autocommit
showardc1a98d12010-01-15 00:22:22 +0000278 where_clause, values = self._where_clause(where)
279 cmd.append(where_clause)
jadmanski0afbb632008-06-06 21:10:57 +0000280 sql = ' '.join(cmd)
281 self.dprint('%s %s' % (sql, values))
mbligh048e1c92007-10-07 00:10:33 +0000282
jadmanski0afbb632008-06-06 21:10:57 +0000283 self._exec_sql_with_commit(sql, values, commit)
mbligh048e1c92007-10-07 00:10:33 +0000284
mbligh7a41a862007-11-30 17:44:24 +0000285
jadmanski0afbb632008-06-06 21:10:57 +0000286 def update(self, table, data, where, commit = None):
287 """\
288 'update table set data values (%s ... %s) where ...'
mbligh2aaeb672007-10-01 14:54:18 +0000289
jadmanski0afbb632008-06-06 21:10:57 +0000290 data:
291 dictionary of fields and data
292 """
mblighd876f452008-12-03 15:09:17 +0000293 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000294 commit = self.autocommit
295 cmd = 'update %s ' % table
296 fields = data.keys()
showardc1a98d12010-01-15 00:22:22 +0000297 data_refs = [self._quote(field) + '=%s' for field in fields]
jadmanski0afbb632008-06-06 21:10:57 +0000298 data_values = [data[field] for field in fields]
jadmanski74eebf32008-07-15 20:04:42 +0000299 cmd += ' set ' + ', '.join(data_refs)
mbligh2aaeb672007-10-01 14:54:18 +0000300
showardc1a98d12010-01-15 00:22:22 +0000301 where_clause, where_values = self._where_clause(where)
302 cmd += where_clause
mbligh2aaeb672007-10-01 14:54:18 +0000303
jadmanski0afbb632008-06-06 21:10:57 +0000304 values = data_values + where_values
jadmanski74eebf32008-07-15 20:04:42 +0000305 self.dprint('%s %s' % (cmd, values))
mbligh2aaeb672007-10-01 14:54:18 +0000306
jadmanski0afbb632008-06-06 21:10:57 +0000307 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000308
309
jadmanski0afbb632008-06-06 21:10:57 +0000310 def delete_job(self, tag, commit = None):
311 job_idx = self.find_job(tag)
312 for test_idx in self.find_tests(job_idx):
313 where = {'test_idx' : test_idx}
showardeab66ce2009-12-23 00:03:56 +0000314 self.delete('tko_iteration_result', where)
315 self.delete('tko_iteration_attributes', where)
316 self.delete('tko_test_attributes', where)
317 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000318 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000319 self.delete('tko_tests', where)
320 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000321
apw7a7316b2008-02-21 17:42:05 +0000322
jadmanski0afbb632008-06-06 21:10:57 +0000323 def insert_job(self, tag, job, commit = None):
324 job.machine_idx = self.lookup_machine(job.machine)
325 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000326 job.machine_idx = self.insert_machine(job, commit=commit)
327 else:
328 self.update_machine_information(job, commit=commit)
329
showardc1c1caf2009-09-08 16:26:50 +0000330 afe_job_id = None
331 pattern = re.compile('^([0-9]+)-.+/.+$')
332 match = pattern.match(tag)
333 if match:
334 afe_job_id = match.group(1)
335
showard0fec8a02009-12-04 01:19:54 +0000336 data = {'tag':tag,
337 'label': job.label,
338 'username': job.user,
339 'machine_idx': job.machine_idx,
340 'queued_time': job.queued_time,
341 'started_time': job.started_time,
342 'finished_time': job.finished_time,
343 'afe_job_id': afe_job_id}
344 is_update = hasattr(job, 'index')
345 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000346 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000347 else:
showardeab66ce2009-12-23 00:03:56 +0000348 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000349 job.index = self.get_last_autonumber_value()
showardc1a98d12010-01-15 00:22:22 +0000350 self.update_job_keyvals(job, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000351 for test in job.tests:
352 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000353
mbligh237bed32007-09-05 13:05:57 +0000354
showardc1a98d12010-01-15 00:22:22 +0000355 def update_job_keyvals(self, job, commit=None):
356 for key, value in job.keyval_dict.iteritems():
357 where = {'job_id': job.index, 'key': key}
358 data = dict(where, value=value)
359 exists = self.select('id', 'tko_job_keyvals', where=where)
360
361 if exists:
362 self.update('tko_job_keyvals', data, where=where, commit=commit)
363 else:
364 self.insert('tko_job_keyvals', data, commit=commit)
365
366
jadmanski0afbb632008-06-06 21:10:57 +0000367 def insert_test(self, job, test, commit = None):
368 kver = self.insert_kernel(test.kernel, commit=commit)
369 data = {'job_idx':job.index, 'test':test.testname,
370 'subdir':test.subdir, 'kernel_idx':kver,
371 'status':self.status_idx[test.status],
372 'reason':test.reason, 'machine_idx':job.machine_idx,
373 'started_time': test.started_time,
374 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000375 is_update = hasattr(test, "test_idx")
376 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000377 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000378 self.update('tko_tests', data,
379 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000380 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000381 self.delete('tko_iteration_result', where)
382 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000383 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000384 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000385 else:
showardeab66ce2009-12-23 00:03:56 +0000386 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000387 test_idx = test.test_idx = self.get_last_autonumber_value()
388 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000389
jadmanski0afbb632008-06-06 21:10:57 +0000390 for i in test.iterations:
391 data['iteration'] = i.index
392 for key, value in i.attr_keyval.iteritems():
393 data['attribute'] = key
394 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000395 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000396 commit=commit)
397 for key, value in i.perf_keyval.iteritems():
398 data['attribute'] = key
399 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000400 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000401 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000402
jadmanski0afbb632008-06-06 21:10:57 +0000403 for key, value in test.attributes.iteritems():
404 data = {'test_idx': test_idx, 'attribute': key,
405 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000406 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000407
jadmanski9b6babf2009-04-21 17:57:40 +0000408 if not is_update:
409 for label_index in test.labels:
410 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000411 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000412
mbligh056d0d32006-10-08 22:31:10 +0000413
jadmanski0afbb632008-06-06 21:10:57 +0000414 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000415 if self.machine_group or not self.machine_map:
416 return
jadmanski0afbb632008-06-06 21:10:57 +0000417 for line in open(self.machine_map, 'r').readlines():
418 (machine, group) = line.split()
419 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000420
421
showard71b94312009-08-20 23:40:02 +0000422 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000423 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000424 group = job.machine_group
425 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000426
427 if not group:
showard71b94312009-08-20 23:40:02 +0000428 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000429 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000430 if group == hostname and owner:
431 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000432
showard71b94312009-08-20 23:40:02 +0000433 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
434
435
436 def insert_machine(self, job, commit = None):
437 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000438 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000439 return self.get_last_autonumber_value()
440
441
showard71b94312009-08-20 23:40:02 +0000442 def update_machine_information(self, job, commit = None):
443 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000444 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000445 where={'hostname': machine_info['hostname']},
446 commit=commit)
447
448
jadmanski0afbb632008-06-06 21:10:57 +0000449 def lookup_machine(self, hostname):
450 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000451 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000452 if rows:
453 return rows[0][0]
454 else:
455 return None
456
457
458 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000459 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000460 {'kernel_hash':kernel.kernel_hash})
461 if rows:
462 return rows[0][0]
463 else:
464 return None
465
466
467 def insert_kernel(self, kernel, commit = None):
468 kver = self.lookup_kernel(kernel)
469 if kver:
470 return kver
471
472 # If this kernel has any significant patches, append their hash
473 # as diferentiator.
474 printable = kernel.base
475 patch_count = 0
476 for patch in kernel.patches:
477 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
478 patch.reference)
479 if not match:
480 patch_count += 1
481
showardeab66ce2009-12-23 00:03:56 +0000482 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000483 {'base':kernel.base,
484 'kernel_hash':kernel.kernel_hash,
485 'printable':printable},
486 commit=commit)
487 kver = self.get_last_autonumber_value()
488
489 if patch_count > 0:
490 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000491 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000492 {'printable':printable},
493 {'kernel_idx':kver})
494
495 for patch in kernel.patches:
496 self.insert_patch(kver, patch, commit=commit)
497 return kver
498
499
500 def insert_patch(self, kver, patch, commit = None):
501 print patch.reference
502 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000503 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000504 {'kernel_idx': kver,
505 'name':name,
506 'url':patch.reference,
507 'hash':patch.hash},
508 commit=commit)
509
510
jadmanski74eebf32008-07-15 20:04:42 +0000511 def find_test(self, job_idx, testname, subdir):
512 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000513 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000514 if rows:
515 return rows[0][0]
516 else:
517 return None
518
519
520 def find_tests(self, job_idx):
521 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000522 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000523 if rows:
524 return [row[0] for row in rows]
525 else:
526 return []
527
528
529 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000530 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000531 if rows:
532 return rows[0][0]
533 else:
534 return None
mblighaf25f062007-12-03 17:48:35 +0000535
536
mbligh96cf0512008-04-17 15:25:38 +0000537def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000538 """Get the database type name to use from the global config."""
539 get_value = global_config.global_config.get_config_value
showard250d84d2010-01-12 21:59:48 +0000540 return "db_" + get_value("AUTOTEST_WEB", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000541
mbligh96cf0512008-04-17 15:25:38 +0000542
543def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000544 """Retrieves the appropriate error class by name from the database
545 module."""
546 db_module = __import__("autotest_lib.tko." + _get_db_type(),
547 globals(), locals(), ["driver"])
548 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000549
550
551def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000552 """Creates an instance of the database class with the arguments
553 provided in args and dargs, using the database type specified by
554 the global configuration (defaulting to mysql)."""
555 db_type = _get_db_type()
556 db_module = __import__("autotest_lib.tko." + db_type, globals(),
557 locals(), [db_type])
558 db = getattr(db_module, db_type)(*args, **dargs)
559 return db