blob: 140a0f89bf6400efc1b5a20836d32d0462383c8c [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']
415 self.insert('tko_iteration_perf_value', data, commit=commit)
416
jadmanski0afbb632008-06-06 21:10:57 +0000417 for key, value in test.attributes.iteritems():
418 data = {'test_idx': test_idx, 'attribute': key,
419 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000420 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000421
jadmanski9b6babf2009-04-21 17:57:40 +0000422 if not is_update:
423 for label_index in test.labels:
424 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000425 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000426
mbligh056d0d32006-10-08 22:31:10 +0000427
jadmanski0afbb632008-06-06 21:10:57 +0000428 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000429 if self.machine_group or not self.machine_map:
430 return
jadmanski0afbb632008-06-06 21:10:57 +0000431 for line in open(self.machine_map, 'r').readlines():
432 (machine, group) = line.split()
433 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000434
435
showard71b94312009-08-20 23:40:02 +0000436 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000437 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000438 group = job.machine_group
439 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000440
441 if not group:
showard71b94312009-08-20 23:40:02 +0000442 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000443 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000444 if group == hostname and owner:
445 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000446
showard71b94312009-08-20 23:40:02 +0000447 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
448
449
450 def insert_machine(self, job, commit = None):
451 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000452 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000453 return self.get_last_autonumber_value()
454
455
showard71b94312009-08-20 23:40:02 +0000456 def update_machine_information(self, job, commit = None):
457 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000458 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000459 where={'hostname': machine_info['hostname']},
460 commit=commit)
461
462
jadmanski0afbb632008-06-06 21:10:57 +0000463 def lookup_machine(self, hostname):
464 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000465 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000466 if rows:
467 return rows[0][0]
468 else:
469 return None
470
471
472 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000473 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000474 {'kernel_hash':kernel.kernel_hash})
475 if rows:
476 return rows[0][0]
477 else:
478 return None
479
480
481 def insert_kernel(self, kernel, commit = None):
482 kver = self.lookup_kernel(kernel)
483 if kver:
484 return kver
485
486 # If this kernel has any significant patches, append their hash
487 # as diferentiator.
488 printable = kernel.base
489 patch_count = 0
490 for patch in kernel.patches:
491 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
492 patch.reference)
493 if not match:
494 patch_count += 1
495
showardeab66ce2009-12-23 00:03:56 +0000496 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000497 {'base':kernel.base,
498 'kernel_hash':kernel.kernel_hash,
499 'printable':printable},
500 commit=commit)
501 kver = self.get_last_autonumber_value()
502
503 if patch_count > 0:
504 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000505 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000506 {'printable':printable},
507 {'kernel_idx':kver})
508
509 for patch in kernel.patches:
510 self.insert_patch(kver, patch, commit=commit)
511 return kver
512
513
514 def insert_patch(self, kver, patch, commit = None):
515 print patch.reference
516 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000517 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000518 {'kernel_idx': kver,
519 'name':name,
520 'url':patch.reference,
521 'hash':patch.hash},
522 commit=commit)
523
524
jadmanski74eebf32008-07-15 20:04:42 +0000525 def find_test(self, job_idx, testname, subdir):
526 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000527 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000528 if rows:
529 return rows[0][0]
530 else:
531 return None
532
533
534 def find_tests(self, job_idx):
535 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000536 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000537 if rows:
538 return [row[0] for row in rows]
539 else:
540 return []
541
542
543 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000544 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000545 if rows:
546 return rows[0][0]
547 else:
548 return None
mblighaf25f062007-12-03 17:48:35 +0000549
550
mbligh96cf0512008-04-17 15:25:38 +0000551def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000552 """Get the database type name to use from the global config."""
553 get_value = global_config.global_config.get_config_value
showard250d84d2010-01-12 21:59:48 +0000554 return "db_" + get_value("AUTOTEST_WEB", "db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000555
mbligh96cf0512008-04-17 15:25:38 +0000556
557def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000558 """Retrieves the appropriate error class by name from the database
559 module."""
560 db_module = __import__("autotest_lib.tko." + _get_db_type(),
561 globals(), locals(), ["driver"])
562 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000563
564
565def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000566 """Creates an instance of the database class with the arguments
567 provided in args and dargs, using the database type specified by
568 the global configuration (defaulting to mysql)."""
569 db_type = _get_db_type()
570 db_module = __import__("autotest_lib.tko." + db_type, globals(),
571 locals(), [db_type])
572 db = getattr(db_module, db_type)(*args, **dargs)
573 return db