blob: 536e3cc030661c7dbaa0b4b6291640326ffefe98 [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:
46 self.host = get_value("TKO", "host")
47 if database:
48 self.database = database
49 else:
50 self.database = get_value("TKO", "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:
56 self.user = get_value("TKO", "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:
60 self.password = get_value("TKO", "password")
mbligh65acae52008-04-24 20:21:55 +000061
jadmanski0afbb632008-06-06 21:10:57 +000062 # grab the timeout configuration
63 self.query_timeout = get_value("TKO", "query_timeout",
64 type=int, default=3600)
65 self.min_delay = get_value("TKO", "min_retry_delay", type=int,
66 default=20)
67 self.max_delay = get_value("TKO", "max_retry_delay", type=int,
68 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
jadmanski0afbb632008-06-06 21:10:57 +0000142 def select(self, fields, table, where, wherein={},
143 distinct = False, group_by = None, max_rows = None):
144 """\
145 This selects all the fields requested from a
146 specific table with a particular where clause.
147 The where clause can either be a dictionary of
148 field=value pairs, a string, or a tuple of (string,
149 a list of values). The last option is what you
150 should use when accepting user input as it'll
151 protect you against sql injection attacks (if
152 all user data is placed in the array rather than
153 the raw SQL).
mbligh12eebfa2008-01-03 02:01:53 +0000154
jadmanski0afbb632008-06-06 21:10:57 +0000155 For example:
156 where = ("a = %s AND b = %s", ['val', 'val'])
157 is better than
158 where = "a = 'val' AND b = 'val'"
159 """
160 cmd = ['select']
161 if distinct:
162 cmd.append('distinct')
163 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +0000164
jadmanski0afbb632008-06-06 21:10:57 +0000165 values = []
166 if where and isinstance(where, types.DictionaryType):
jadmanski74eebf32008-07-15 20:04:42 +0000167 # key/value pairs (which should be equal, or None for null)
168 keys, values = [], []
169 for field, value in where.iteritems():
170 if value is None:
171 keys.append(field + ' is null')
172 else:
173 keys.append(field + '=%s')
174 values.append(value)
jadmanski0afbb632008-06-06 21:10:57 +0000175 cmd.append(' where ' + ' and '.join(keys))
176 elif where and isinstance(where, types.StringTypes):
177 # the exact string
178 cmd.append(' where ' + where)
179 elif where and isinstance(where, types.TupleType):
180 # preformatted where clause + values
181 (sql, vals) = where
182 values = vals
183 cmd.append(' where (%s) ' % sql)
mbligh53d14252007-09-12 16:33:14 +0000184
jadmanski0afbb632008-06-06 21:10:57 +0000185 # TODO: this assumes there's a where clause...bad
186 if wherein and isinstance(wherein, types.DictionaryType):
187 keys_in = ["%s in (%s) " % (field, ','.join(where))
188 for field, where in wherein.iteritems()]
189 cmd.append(' and '+' and '.join(keys_in))
mbligh96cf0512008-04-17 15:25:38 +0000190
jadmanski0afbb632008-06-06 21:10:57 +0000191 if group_by:
192 cmd.append(' GROUP BY ' + group_by)
mbligh83f63a02007-12-12 19:13:04 +0000193
jadmanski0afbb632008-06-06 21:10:57 +0000194 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh96cf0512008-04-17 15:25:38 +0000195
jadmanski0afbb632008-06-06 21:10:57 +0000196 # create a re-runable function for executing the query
197 def exec_sql():
198 sql = ' '.join(cmd)
199 numRec = self.cur.execute(sql, values)
mblighd876f452008-12-03 15:09:17 +0000200 if max_rows is not None and numRec > max_rows:
jadmanski0afbb632008-06-06 21:10:57 +0000201 msg = 'Exceeded allowed number of records'
202 raise MySQLTooManyRows(msg)
203 return self.cur.fetchall()
mbligh96cf0512008-04-17 15:25:38 +0000204
jadmanski0afbb632008-06-06 21:10:57 +0000205 # run the query, re-trying after operational errors
206 if self.autocommit:
207 return self.run_with_retry(exec_sql)
208 else:
209 return exec_sql()
mblighd5c33db2006-10-08 21:34:16 +0000210
mbligh056d0d32006-10-08 22:31:10 +0000211
jadmanski0afbb632008-06-06 21:10:57 +0000212 def select_sql(self, fields, table, sql, values):
213 """\
214 select fields from table "sql"
215 """
216 cmd = 'select %s from %s %s' % (fields, table, sql)
217 self.dprint(cmd)
mbligh414c69e2007-10-05 15:13:06 +0000218
jadmanski0afbb632008-06-06 21:10:57 +0000219 # create a -re-runable function for executing the query
220 def exec_sql():
221 self.cur.execute(cmd, values)
222 return self.cur.fetchall()
mbligh96b9a5a2007-11-24 19:32:20 +0000223
jadmanski0afbb632008-06-06 21:10:57 +0000224 # run the query, re-trying after operational errors
225 if self.autocommit:
226 return self.run_with_retry(exec_sql)
227 else:
228 return exec_sql()
mbligh96b9a5a2007-11-24 19:32:20 +0000229
mbligh608c3252007-08-31 13:53:00 +0000230
jadmanski0afbb632008-06-06 21:10:57 +0000231 def _exec_sql_with_commit(self, sql, values, commit):
232 if self.autocommit:
233 # re-run the query until it succeeds
234 def exec_sql():
235 self.cur.execute(sql, values)
236 self.con.commit()
237 self.run_with_retry(exec_sql)
238 else:
239 # take one shot at running the query
240 self.cur.execute(sql, values)
241 if commit:
242 self.con.commit()
mbligh96b9a5a2007-11-24 19:32:20 +0000243
mbligh2bd48872007-09-20 18:32:25 +0000244
jadmanskib591fba2008-09-10 16:19:22 +0000245 def insert(self, table, data, commit=None):
jadmanski0afbb632008-06-06 21:10:57 +0000246 """\
247 'insert into table (keys) values (%s ... %s)', values
mbligh96cf0512008-04-17 15:25:38 +0000248
jadmanski0afbb632008-06-06 21:10:57 +0000249 data:
250 dictionary of fields and data
251 """
252 fields = data.keys()
253 refs = ['%s' for field in fields]
254 values = [data[field] for field in fields]
255 cmd = 'insert into %s (%s) values (%s)' % \
256 (table, ','.join(fields), ','.join(refs))
257 self.dprint('%s %s' % (cmd, values))
mblighe9cf9d42007-08-31 08:56:00 +0000258
jadmanski0afbb632008-06-06 21:10:57 +0000259 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000260
mbligh048e1c92007-10-07 00:10:33 +0000261
jadmanski0afbb632008-06-06 21:10:57 +0000262 def delete(self, table, where, commit = None):
263 cmd = ['delete from', table]
mblighd876f452008-12-03 15:09:17 +0000264 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000265 commit = self.autocommit
266 if where and isinstance(where, types.DictionaryType):
267 keys = [field + '=%s' for field in where.keys()]
268 values = [where[field] for field in where.keys()]
269 cmd += ['where', ' and '.join(keys)]
270 sql = ' '.join(cmd)
271 self.dprint('%s %s' % (sql, values))
mbligh048e1c92007-10-07 00:10:33 +0000272
jadmanski0afbb632008-06-06 21:10:57 +0000273 self._exec_sql_with_commit(sql, values, commit)
mbligh048e1c92007-10-07 00:10:33 +0000274
mbligh7a41a862007-11-30 17:44:24 +0000275
jadmanski0afbb632008-06-06 21:10:57 +0000276 def update(self, table, data, where, commit = None):
277 """\
278 'update table set data values (%s ... %s) where ...'
mbligh2aaeb672007-10-01 14:54:18 +0000279
jadmanski0afbb632008-06-06 21:10:57 +0000280 data:
281 dictionary of fields and data
282 """
mblighd876f452008-12-03 15:09:17 +0000283 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000284 commit = self.autocommit
285 cmd = 'update %s ' % table
286 fields = data.keys()
287 data_refs = [field + '=%s' for field in fields]
288 data_values = [data[field] for field in fields]
jadmanski74eebf32008-07-15 20:04:42 +0000289 cmd += ' set ' + ', '.join(data_refs)
mbligh2aaeb672007-10-01 14:54:18 +0000290
jadmanski0afbb632008-06-06 21:10:57 +0000291 where_keys = [field + '=%s' for field in where.keys()]
292 where_values = [where[field] for field in where.keys()]
293 cmd += ' where ' + ' and '.join(where_keys)
mbligh2aaeb672007-10-01 14:54:18 +0000294
jadmanski0afbb632008-06-06 21:10:57 +0000295 values = data_values + where_values
jadmanski74eebf32008-07-15 20:04:42 +0000296 self.dprint('%s %s' % (cmd, values))
mbligh2aaeb672007-10-01 14:54:18 +0000297
jadmanski0afbb632008-06-06 21:10:57 +0000298 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000299
300
jadmanski0afbb632008-06-06 21:10:57 +0000301 def delete_job(self, tag, commit = None):
302 job_idx = self.find_job(tag)
303 for test_idx in self.find_tests(job_idx):
304 where = {'test_idx' : test_idx}
showardeab66ce2009-12-23 00:03:56 +0000305 self.delete('tko_iteration_result', where)
306 self.delete('tko_iteration_attributes', where)
307 self.delete('tko_test_attributes', where)
308 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000309 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000310 self.delete('tko_tests', where)
311 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000312
apw7a7316b2008-02-21 17:42:05 +0000313
jadmanski0afbb632008-06-06 21:10:57 +0000314 def insert_job(self, tag, job, commit = None):
315 job.machine_idx = self.lookup_machine(job.machine)
316 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000317 job.machine_idx = self.insert_machine(job, commit=commit)
318 else:
319 self.update_machine_information(job, commit=commit)
320
showardc1c1caf2009-09-08 16:26:50 +0000321 afe_job_id = None
322 pattern = re.compile('^([0-9]+)-.+/.+$')
323 match = pattern.match(tag)
324 if match:
325 afe_job_id = match.group(1)
326
showard0fec8a02009-12-04 01:19:54 +0000327 data = {'tag':tag,
328 'label': job.label,
329 'username': job.user,
330 'machine_idx': job.machine_idx,
331 'queued_time': job.queued_time,
332 'started_time': job.started_time,
333 'finished_time': job.finished_time,
334 'afe_job_id': afe_job_id}
335 is_update = hasattr(job, 'index')
336 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000337 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000338 else:
showardeab66ce2009-12-23 00:03:56 +0000339 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000340 job.index = self.get_last_autonumber_value()
jadmanski0afbb632008-06-06 21:10:57 +0000341 for test in job.tests:
342 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000343
mbligh237bed32007-09-05 13:05:57 +0000344
jadmanski0afbb632008-06-06 21:10:57 +0000345 def insert_test(self, job, test, commit = None):
346 kver = self.insert_kernel(test.kernel, commit=commit)
347 data = {'job_idx':job.index, 'test':test.testname,
348 'subdir':test.subdir, 'kernel_idx':kver,
349 'status':self.status_idx[test.status],
350 'reason':test.reason, 'machine_idx':job.machine_idx,
351 'started_time': test.started_time,
352 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000353 is_update = hasattr(test, "test_idx")
354 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000355 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000356 self.update('tko_tests', data,
357 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000358 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000359 self.delete('tko_iteration_result', where)
360 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000361 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000362 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000363 else:
showardeab66ce2009-12-23 00:03:56 +0000364 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000365 test_idx = test.test_idx = self.get_last_autonumber_value()
366 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000367
jadmanski0afbb632008-06-06 21:10:57 +0000368 for i in test.iterations:
369 data['iteration'] = i.index
370 for key, value in i.attr_keyval.iteritems():
371 data['attribute'] = key
372 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000373 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000374 commit=commit)
375 for key, value in i.perf_keyval.iteritems():
376 data['attribute'] = key
377 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000378 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000379 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000380
jadmanski0afbb632008-06-06 21:10:57 +0000381 for key, value in test.attributes.iteritems():
382 data = {'test_idx': test_idx, 'attribute': key,
383 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000384 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000385
jadmanski9b6babf2009-04-21 17:57:40 +0000386 if not is_update:
387 for label_index in test.labels:
388 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000389 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000390
mbligh056d0d32006-10-08 22:31:10 +0000391
jadmanski0afbb632008-06-06 21:10:57 +0000392 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000393 if self.machine_group or not self.machine_map:
394 return
jadmanski0afbb632008-06-06 21:10:57 +0000395 for line in open(self.machine_map, 'r').readlines():
396 (machine, group) = line.split()
397 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000398
399
showard71b94312009-08-20 23:40:02 +0000400 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000401 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000402 group = job.machine_group
403 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000404
405 if not group:
showard71b94312009-08-20 23:40:02 +0000406 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000407 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000408 if group == hostname and owner:
409 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000410
showard71b94312009-08-20 23:40:02 +0000411 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
412
413
414 def insert_machine(self, job, commit = None):
415 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000416 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000417 return self.get_last_autonumber_value()
418
419
showard71b94312009-08-20 23:40:02 +0000420 def update_machine_information(self, job, commit = None):
421 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000422 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000423 where={'hostname': machine_info['hostname']},
424 commit=commit)
425
426
jadmanski0afbb632008-06-06 21:10:57 +0000427 def lookup_machine(self, hostname):
428 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000429 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000430 if rows:
431 return rows[0][0]
432 else:
433 return None
434
435
436 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000437 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000438 {'kernel_hash':kernel.kernel_hash})
439 if rows:
440 return rows[0][0]
441 else:
442 return None
443
444
445 def insert_kernel(self, kernel, commit = None):
446 kver = self.lookup_kernel(kernel)
447 if kver:
448 return kver
449
450 # If this kernel has any significant patches, append their hash
451 # as diferentiator.
452 printable = kernel.base
453 patch_count = 0
454 for patch in kernel.patches:
455 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
456 patch.reference)
457 if not match:
458 patch_count += 1
459
showardeab66ce2009-12-23 00:03:56 +0000460 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000461 {'base':kernel.base,
462 'kernel_hash':kernel.kernel_hash,
463 'printable':printable},
464 commit=commit)
465 kver = self.get_last_autonumber_value()
466
467 if patch_count > 0:
468 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000469 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000470 {'printable':printable},
471 {'kernel_idx':kver})
472
473 for patch in kernel.patches:
474 self.insert_patch(kver, patch, commit=commit)
475 return kver
476
477
478 def insert_patch(self, kver, patch, commit = None):
479 print patch.reference
480 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000481 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000482 {'kernel_idx': kver,
483 'name':name,
484 'url':patch.reference,
485 'hash':patch.hash},
486 commit=commit)
487
488
jadmanski74eebf32008-07-15 20:04:42 +0000489 def find_test(self, job_idx, testname, subdir):
490 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000491 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000492 if rows:
493 return rows[0][0]
494 else:
495 return None
496
497
498 def find_tests(self, job_idx):
499 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000500 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000501 if rows:
502 return [row[0] for row in rows]
503 else:
504 return []
505
506
507 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000508 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000509 if rows:
510 return rows[0][0]
511 else:
512 return None
mblighaf25f062007-12-03 17:48:35 +0000513
514
mbligh96cf0512008-04-17 15:25:38 +0000515def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000516 """Get the database type name to use from the global config."""
517 get_value = global_config.global_config.get_config_value
518 return "db_" + get_value("TKO", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000519
mbligh96cf0512008-04-17 15:25:38 +0000520
521def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000522 """Retrieves the appropriate error class by name from the database
523 module."""
524 db_module = __import__("autotest_lib.tko." + _get_db_type(),
525 globals(), locals(), ["driver"])
526 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000527
528
529def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000530 """Creates an instance of the database class with the arguments
531 provided in args and dargs, using the database type specified by
532 the global configuration (defaulting to mysql)."""
533 db_type = _get_db_type()
534 db_module = __import__("autotest_lib.tko." + db_type, globals(),
535 locals(), [db_type])
536 db = getattr(db_module, db_type)(*args, **dargs)
537 return db