blob: 2ba4fe96899838e3f7136892a9bd8d615639353b [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)
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700320 self.delete('tko_iteration_perf_value', where)
showardeab66ce2009-12-23 00:03:56 +0000321 self.delete('tko_iteration_attributes', where)
322 self.delete('tko_test_attributes', where)
323 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000324 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000325 self.delete('tko_tests', where)
326 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000327
apw7a7316b2008-02-21 17:42:05 +0000328
jadmanski0afbb632008-06-06 21:10:57 +0000329 def insert_job(self, tag, job, commit = None):
330 job.machine_idx = self.lookup_machine(job.machine)
331 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000332 job.machine_idx = self.insert_machine(job, commit=commit)
333 else:
334 self.update_machine_information(job, commit=commit)
335
jamesrena12b8a02010-06-16 23:28:23 +0000336 afe_job_id = utils.get_afe_job_id(tag)
showardc1c1caf2009-09-08 16:26:50 +0000337
showard0fec8a02009-12-04 01:19:54 +0000338 data = {'tag':tag,
339 'label': job.label,
340 'username': job.user,
341 'machine_idx': job.machine_idx,
342 'queued_time': job.queued_time,
343 'started_time': job.started_time,
344 'finished_time': job.finished_time,
345 'afe_job_id': afe_job_id}
346 is_update = hasattr(job, 'index')
347 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000348 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000349 else:
showardeab66ce2009-12-23 00:03:56 +0000350 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000351 job.index = self.get_last_autonumber_value()
showardc1a98d12010-01-15 00:22:22 +0000352 self.update_job_keyvals(job, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000353 for test in job.tests:
354 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000355
mbligh237bed32007-09-05 13:05:57 +0000356
showardc1a98d12010-01-15 00:22:22 +0000357 def update_job_keyvals(self, job, commit=None):
358 for key, value in job.keyval_dict.iteritems():
359 where = {'job_id': job.index, 'key': key}
360 data = dict(where, value=value)
361 exists = self.select('id', 'tko_job_keyvals', where=where)
362
363 if exists:
364 self.update('tko_job_keyvals', data, where=where, commit=commit)
365 else:
366 self.insert('tko_job_keyvals', data, commit=commit)
367
368
jadmanski0afbb632008-06-06 21:10:57 +0000369 def insert_test(self, job, test, commit = None):
370 kver = self.insert_kernel(test.kernel, commit=commit)
371 data = {'job_idx':job.index, 'test':test.testname,
372 'subdir':test.subdir, 'kernel_idx':kver,
373 'status':self.status_idx[test.status],
374 'reason':test.reason, 'machine_idx':job.machine_idx,
375 'started_time': test.started_time,
376 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000377 is_update = hasattr(test, "test_idx")
378 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000379 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000380 self.update('tko_tests', data,
381 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000382 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000383 self.delete('tko_iteration_result', where)
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700384 self.delete('tko_iteration_perf_value', where)
showardeab66ce2009-12-23 00:03:56 +0000385 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000386 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000387 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000388 else:
showardeab66ce2009-12-23 00:03:56 +0000389 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000390 test_idx = test.test_idx = self.get_last_autonumber_value()
391 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000392
jadmanski0afbb632008-06-06 21:10:57 +0000393 for i in test.iterations:
394 data['iteration'] = i.index
395 for key, value in i.attr_keyval.iteritems():
396 data['attribute'] = key
397 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000398 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000399 commit=commit)
400 for key, value in i.perf_keyval.iteritems():
401 data['attribute'] = key
402 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000403 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000404 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000405
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700406 data = {'test_idx': test_idx}
407 for i in test.perf_values:
408 data['iteration'] = i.index
409 for perf_dict in i.perf_measurements:
410 data['description'] = perf_dict['description']
411 data['value'] = perf_dict['value']
412 data['stddev'] = perf_dict['stddev']
413 data['units'] = perf_dict['units']
414 data['higher_is_better'] = perf_dict['higher_is_better']
Fang Deng7f24f0b2013-11-12 11:22:16 -0800415 data['graph'] = perf_dict['graph']
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700416 self.insert('tko_iteration_perf_value', data, commit=commit)
417
jadmanski0afbb632008-06-06 21:10:57 +0000418 for key, value in test.attributes.iteritems():
419 data = {'test_idx': test_idx, 'attribute': key,
420 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000421 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000422
jadmanski9b6babf2009-04-21 17:57:40 +0000423 if not is_update:
424 for label_index in test.labels:
425 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000426 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000427
mbligh056d0d32006-10-08 22:31:10 +0000428
jadmanski0afbb632008-06-06 21:10:57 +0000429 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000430 if self.machine_group or not self.machine_map:
431 return
jadmanski0afbb632008-06-06 21:10:57 +0000432 for line in open(self.machine_map, 'r').readlines():
433 (machine, group) = line.split()
434 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000435
436
showard71b94312009-08-20 23:40:02 +0000437 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000438 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000439 group = job.machine_group
440 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000441
442 if not group:
showard71b94312009-08-20 23:40:02 +0000443 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000444 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000445 if group == hostname and owner:
446 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000447
showard71b94312009-08-20 23:40:02 +0000448 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
449
450
451 def insert_machine(self, job, commit = None):
452 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000453 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000454 return self.get_last_autonumber_value()
455
456
showard71b94312009-08-20 23:40:02 +0000457 def update_machine_information(self, job, commit = None):
458 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000459 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000460 where={'hostname': machine_info['hostname']},
461 commit=commit)
462
463
jadmanski0afbb632008-06-06 21:10:57 +0000464 def lookup_machine(self, hostname):
465 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000466 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000467 if rows:
468 return rows[0][0]
469 else:
470 return None
471
472
473 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000474 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000475 {'kernel_hash':kernel.kernel_hash})
476 if rows:
477 return rows[0][0]
478 else:
479 return None
480
481
482 def insert_kernel(self, kernel, commit = None):
483 kver = self.lookup_kernel(kernel)
484 if kver:
485 return kver
486
487 # If this kernel has any significant patches, append their hash
488 # as diferentiator.
489 printable = kernel.base
490 patch_count = 0
491 for patch in kernel.patches:
492 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
493 patch.reference)
494 if not match:
495 patch_count += 1
496
showardeab66ce2009-12-23 00:03:56 +0000497 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000498 {'base':kernel.base,
499 'kernel_hash':kernel.kernel_hash,
500 'printable':printable},
501 commit=commit)
502 kver = self.get_last_autonumber_value()
503
504 if patch_count > 0:
505 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000506 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000507 {'printable':printable},
508 {'kernel_idx':kver})
509
510 for patch in kernel.patches:
511 self.insert_patch(kver, patch, commit=commit)
512 return kver
513
514
515 def insert_patch(self, kver, patch, commit = None):
516 print patch.reference
517 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000518 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000519 {'kernel_idx': kver,
520 'name':name,
521 'url':patch.reference,
522 'hash':patch.hash},
523 commit=commit)
524
525
jadmanski74eebf32008-07-15 20:04:42 +0000526 def find_test(self, job_idx, testname, subdir):
527 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000528 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000529 if rows:
530 return rows[0][0]
531 else:
532 return None
533
534
535 def find_tests(self, job_idx):
536 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000537 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000538 if rows:
539 return [row[0] for row in rows]
540 else:
541 return []
542
543
544 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000545 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000546 if rows:
547 return rows[0][0]
548 else:
549 return None
mblighaf25f062007-12-03 17:48:35 +0000550
551
mbligh96cf0512008-04-17 15:25:38 +0000552def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000553 """Get the database type name to use from the global config."""
554 get_value = global_config.global_config.get_config_value
showard250d84d2010-01-12 21:59:48 +0000555 return "db_" + get_value("AUTOTEST_WEB", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000556
mbligh96cf0512008-04-17 15:25:38 +0000557
558def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000559 """Retrieves the appropriate error class by name from the database
560 module."""
561 db_module = __import__("autotest_lib.tko." + _get_db_type(),
562 globals(), locals(), ["driver"])
563 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000564
565
566def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000567 """Creates an instance of the database class with the arguments
568 provided in args and dargs, using the database type specified by
569 the global configuration (defaulting to mysql)."""
570 db_type = _get_db_type()
571 db_module = __import__("autotest_lib.tko." + db_type, globals(),
572 locals(), [db_type])
573 db = getattr(db_module, db_type)(*args, **dargs)
574 return db