blob: bdce8c71dec2308f828c69e7868dda2cd1083b94 [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):
Jakob Juelich3270e182014-10-13 10:00:43 -070040 # 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:
Jakob Juelich3270e182014-10-13 10:00:43 -070047 self.host = get_value("AUTOTEST_WEB", "global_db_host")
jadmanski0afbb632008-06-06 21:10:57 +000048 if database:
49 self.database = database
50 else:
Jakob Juelich3270e182014-10-13 10:00:43 -070051 self.database = get_value("AUTOTEST_WEB", "global_db_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:
Jakob Juelich3270e182014-10-13 10:00:43 -070057 self.user = get_value("AUTOTEST_WEB", "global_db_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:
Jakob Juelich3270e182014-10-13 10:00:43 -070061 self.password = get_value("AUTOTEST_WEB", "global_db_password")
mbligh65acae52008-04-24 20:21:55 +000062
Michael Spang7a273472014-10-08 12:08:13 -040063 # grab the timeout configuration
Jakob Juelich3270e182014-10-13 10:00:43 -070064 self.query_timeout = get_value("AUTOTEST_WEB",
65 "global_db_query_timeout",
66 type=int, default=3600)
Jakob Juelich475b82b2014-09-30 11:17:07 -070067 self.min_delay = get_value("AUTOTEST_WEB", "global_db_min_retry_delay",
Jakob Juelich3270e182014-10-13 10:00:43 -070068 type=int, default=20)
Jakob Juelich475b82b2014-09-30 11:17:07 -070069 self.max_delay = get_value("AUTOTEST_WEB", "global_db_max_retry_delay",
Jakob Juelich3270e182014-10-13 10:00:43 -070070 type=int, default=60)
mbligh65acae52008-04-24 20:21:55 +000071
72
jadmanski0afbb632008-06-06 21:10:57 +000073 def _init_db(self):
74 # make sure we clean up any existing connection
75 if self.con:
76 self.con.close()
77 self.con = None
mbligh65acae52008-04-24 20:21:55 +000078
jadmanski0afbb632008-06-06 21:10:57 +000079 # create the db connection and cursor
80 self.con = self.connect(self.host, self.database,
81 self.user, self.password)
82 self.cur = self.con.cursor()
mbligh96cf0512008-04-17 15:25:38 +000083
84
jadmanski0afbb632008-06-06 21:10:57 +000085 def _random_delay(self):
86 delay = random.randint(self.min_delay, self.max_delay)
87 time.sleep(delay)
mbligh65acae52008-04-24 20:21:55 +000088
89
jadmanski0afbb632008-06-06 21:10:57 +000090 def run_with_retry(self, function, *args, **dargs):
91 """Call function(*args, **dargs) until either it passes
92 without an operational error, or a timeout is reached.
93 This will re-connect to the database, so it is NOT safe
94 to use this inside of a database transaction.
jadmanskie7a69092008-05-29 21:03:13 +000095
jadmanski0afbb632008-06-06 21:10:57 +000096 It can be safely used with transactions, but the
97 transaction start & end must be completely contained
98 within the call to 'function'."""
99 OperationalError = _get_error_class("OperationalError")
mbligh65acae52008-04-24 20:21:55 +0000100
jadmanski0afbb632008-06-06 21:10:57 +0000101 success = False
102 start_time = time.time()
103 while not success:
104 try:
105 result = function(*args, **dargs)
106 except OperationalError, e:
107 self._log_operational_error(e)
108 stop_time = time.time()
109 elapsed_time = stop_time - start_time
110 if elapsed_time > self.query_timeout:
111 raise
112 else:
113 try:
114 self._random_delay()
115 self._init_db()
116 except OperationalError, e:
117 self._log_operational_error(e)
118 else:
119 success = True
120 return result
mbligh96cf0512008-04-17 15:25:38 +0000121
122
jadmanski0afbb632008-06-06 21:10:57 +0000123 def _log_operational_error(self, e):
mbligh097407d2009-02-17 15:49:37 +0000124 msg = ("%s: An operational error occured during a database "
jadmanski5d4c27e2009-03-02 16:45:42 +0000125 "operation: %s" % (time.strftime("%X %x"), str(e)))
jadmanski0afbb632008-06-06 21:10:57 +0000126 print >> sys.stderr, msg
127 sys.stderr.flush() # we want these msgs to show up immediately
jadmanski60d4fa62008-05-06 22:49:41 +0000128
129
jadmanski0afbb632008-06-06 21:10:57 +0000130 def dprint(self, value):
131 if self.debug:
132 sys.stdout.write('SQL: ' + str(value) + '\n')
mbligh8e1ab172007-09-13 17:29:56 +0000133
mblighd5c33db2006-10-08 21:34:16 +0000134
jadmanski0afbb632008-06-06 21:10:57 +0000135 def commit(self):
136 self.con.commit()
mbligh432bad42007-10-09 19:56:07 +0000137
138
Simran Basie129a962012-08-31 13:03:53 -0700139 def rollback(self):
140 self.con.rollback()
141
142
jadmanski0afbb632008-06-06 21:10:57 +0000143 def get_last_autonumber_value(self):
144 self.cur.execute('SELECT LAST_INSERT_ID()', [])
145 return self.cur.fetchall()[0][0]
mblighe12b8612008-02-12 20:58:14 +0000146
147
showardc1a98d12010-01-15 00:22:22 +0000148 def _quote(self, field):
149 return '`%s`' % field
150
151
152 def _where_clause(self, where):
153 if not where:
154 return '', []
155
156 if isinstance(where, dict):
157 # key/value pairs (which should be equal, or None for null)
158 keys, values = [], []
159 for field, value in where.iteritems():
160 quoted_field = self._quote(field)
161 if value is None:
162 keys.append(quoted_field + ' is null')
163 else:
164 keys.append(quoted_field + '=%s')
165 values.append(value)
166 where_clause = ' and '.join(keys)
167 elif isinstance(where, basestring):
168 # the exact string
169 where_clause = where
170 values = []
171 elif isinstance(where, tuple):
172 # preformatted where clause + values
173 where_clause, values = where
174 assert where_clause
175 else:
176 raise ValueError('Invalid "where" value: %r' % where)
177
178 return ' WHERE ' + where_clause, values
179
180
181
182 def select(self, fields, table, where, distinct=False, group_by=None,
183 max_rows=None):
jadmanski0afbb632008-06-06 21:10:57 +0000184 """\
185 This selects all the fields requested from a
186 specific table with a particular where clause.
187 The where clause can either be a dictionary of
188 field=value pairs, a string, or a tuple of (string,
189 a list of values). The last option is what you
190 should use when accepting user input as it'll
191 protect you against sql injection attacks (if
192 all user data is placed in the array rather than
193 the raw SQL).
mbligh12eebfa2008-01-03 02:01:53 +0000194
jadmanski0afbb632008-06-06 21:10:57 +0000195 For example:
196 where = ("a = %s AND b = %s", ['val', 'val'])
197 is better than
198 where = "a = 'val' AND b = 'val'"
199 """
200 cmd = ['select']
201 if distinct:
202 cmd.append('distinct')
203 cmd += [fields, 'from', table]
mbligh608c3252007-08-31 13:53:00 +0000204
showardc1a98d12010-01-15 00:22:22 +0000205 where_clause, values = self._where_clause(where)
206 cmd.append(where_clause)
mbligh96cf0512008-04-17 15:25:38 +0000207
jadmanski0afbb632008-06-06 21:10:57 +0000208 if group_by:
209 cmd.append(' GROUP BY ' + group_by)
mbligh83f63a02007-12-12 19:13:04 +0000210
jadmanski0afbb632008-06-06 21:10:57 +0000211 self.dprint('%s %s' % (' '.join(cmd), values))
mbligh96cf0512008-04-17 15:25:38 +0000212
jadmanski0afbb632008-06-06 21:10:57 +0000213 # create a re-runable function for executing the query
214 def exec_sql():
215 sql = ' '.join(cmd)
216 numRec = self.cur.execute(sql, values)
mblighd876f452008-12-03 15:09:17 +0000217 if max_rows is not None and numRec > max_rows:
jadmanski0afbb632008-06-06 21:10:57 +0000218 msg = 'Exceeded allowed number of records'
219 raise MySQLTooManyRows(msg)
220 return self.cur.fetchall()
mbligh96cf0512008-04-17 15:25:38 +0000221
jadmanski0afbb632008-06-06 21:10:57 +0000222 # run the query, re-trying after operational errors
223 if self.autocommit:
224 return self.run_with_retry(exec_sql)
225 else:
226 return exec_sql()
mblighd5c33db2006-10-08 21:34:16 +0000227
mbligh056d0d32006-10-08 22:31:10 +0000228
jadmanski0afbb632008-06-06 21:10:57 +0000229 def select_sql(self, fields, table, sql, values):
230 """\
231 select fields from table "sql"
232 """
233 cmd = 'select %s from %s %s' % (fields, table, sql)
234 self.dprint(cmd)
mbligh414c69e2007-10-05 15:13:06 +0000235
jadmanski0afbb632008-06-06 21:10:57 +0000236 # create a -re-runable function for executing the query
237 def exec_sql():
238 self.cur.execute(cmd, values)
239 return self.cur.fetchall()
mbligh96b9a5a2007-11-24 19:32:20 +0000240
jadmanski0afbb632008-06-06 21:10:57 +0000241 # run the query, re-trying after operational errors
242 if self.autocommit:
243 return self.run_with_retry(exec_sql)
244 else:
245 return exec_sql()
mbligh96b9a5a2007-11-24 19:32:20 +0000246
mbligh608c3252007-08-31 13:53:00 +0000247
jadmanski0afbb632008-06-06 21:10:57 +0000248 def _exec_sql_with_commit(self, sql, values, commit):
249 if self.autocommit:
250 # re-run the query until it succeeds
251 def exec_sql():
252 self.cur.execute(sql, values)
253 self.con.commit()
254 self.run_with_retry(exec_sql)
255 else:
256 # take one shot at running the query
257 self.cur.execute(sql, values)
258 if commit:
259 self.con.commit()
mbligh96b9a5a2007-11-24 19:32:20 +0000260
mbligh2bd48872007-09-20 18:32:25 +0000261
jadmanskib591fba2008-09-10 16:19:22 +0000262 def insert(self, table, data, commit=None):
jadmanski0afbb632008-06-06 21:10:57 +0000263 """\
264 'insert into table (keys) values (%s ... %s)', values
mbligh96cf0512008-04-17 15:25:38 +0000265
jadmanski0afbb632008-06-06 21:10:57 +0000266 data:
267 dictionary of fields and data
268 """
269 fields = data.keys()
270 refs = ['%s' for field in fields]
271 values = [data[field] for field in fields]
showardc1a98d12010-01-15 00:22:22 +0000272 cmd = ('insert into %s (%s) values (%s)' %
273 (table, ','.join(self._quote(field) for field in fields),
274 ','.join(refs)))
jadmanski0afbb632008-06-06 21:10:57 +0000275 self.dprint('%s %s' % (cmd, values))
mblighe9cf9d42007-08-31 08:56:00 +0000276
jadmanski0afbb632008-06-06 21:10:57 +0000277 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000278
mbligh048e1c92007-10-07 00:10:33 +0000279
jadmanski0afbb632008-06-06 21:10:57 +0000280 def delete(self, table, where, commit = None):
281 cmd = ['delete from', table]
mblighd876f452008-12-03 15:09:17 +0000282 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000283 commit = self.autocommit
showardc1a98d12010-01-15 00:22:22 +0000284 where_clause, values = self._where_clause(where)
285 cmd.append(where_clause)
jadmanski0afbb632008-06-06 21:10:57 +0000286 sql = ' '.join(cmd)
287 self.dprint('%s %s' % (sql, values))
mbligh048e1c92007-10-07 00:10:33 +0000288
jadmanski0afbb632008-06-06 21:10:57 +0000289 self._exec_sql_with_commit(sql, values, commit)
mbligh048e1c92007-10-07 00:10:33 +0000290
mbligh7a41a862007-11-30 17:44:24 +0000291
jadmanski0afbb632008-06-06 21:10:57 +0000292 def update(self, table, data, where, commit = None):
293 """\
294 'update table set data values (%s ... %s) where ...'
mbligh2aaeb672007-10-01 14:54:18 +0000295
jadmanski0afbb632008-06-06 21:10:57 +0000296 data:
297 dictionary of fields and data
298 """
mblighd876f452008-12-03 15:09:17 +0000299 if commit is None:
jadmanski0afbb632008-06-06 21:10:57 +0000300 commit = self.autocommit
301 cmd = 'update %s ' % table
302 fields = data.keys()
showardc1a98d12010-01-15 00:22:22 +0000303 data_refs = [self._quote(field) + '=%s' for field in fields]
jadmanski0afbb632008-06-06 21:10:57 +0000304 data_values = [data[field] for field in fields]
jadmanski74eebf32008-07-15 20:04:42 +0000305 cmd += ' set ' + ', '.join(data_refs)
mbligh2aaeb672007-10-01 14:54:18 +0000306
showardc1a98d12010-01-15 00:22:22 +0000307 where_clause, where_values = self._where_clause(where)
308 cmd += where_clause
mbligh2aaeb672007-10-01 14:54:18 +0000309
jadmanski0afbb632008-06-06 21:10:57 +0000310 values = data_values + where_values
jadmanski74eebf32008-07-15 20:04:42 +0000311 self.dprint('%s %s' % (cmd, values))
mbligh2aaeb672007-10-01 14:54:18 +0000312
jadmanski0afbb632008-06-06 21:10:57 +0000313 self._exec_sql_with_commit(cmd, values, commit)
mblighe9cf9d42007-08-31 08:56:00 +0000314
315
jadmanski0afbb632008-06-06 21:10:57 +0000316 def delete_job(self, tag, commit = None):
317 job_idx = self.find_job(tag)
318 for test_idx in self.find_tests(job_idx):
319 where = {'test_idx' : test_idx}
showardeab66ce2009-12-23 00:03:56 +0000320 self.delete('tko_iteration_result', where)
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700321 self.delete('tko_iteration_perf_value', where)
showardeab66ce2009-12-23 00:03:56 +0000322 self.delete('tko_iteration_attributes', where)
323 self.delete('tko_test_attributes', where)
324 self.delete('tko_test_labels_tests', {'test_id': test_idx})
jadmanski0afbb632008-06-06 21:10:57 +0000325 where = {'job_idx' : job_idx}
showardeab66ce2009-12-23 00:03:56 +0000326 self.delete('tko_tests', where)
327 self.delete('tko_jobs', where)
apw7a7316b2008-02-21 17:42:05 +0000328
apw7a7316b2008-02-21 17:42:05 +0000329
jadmanski0afbb632008-06-06 21:10:57 +0000330 def insert_job(self, tag, job, commit = None):
331 job.machine_idx = self.lookup_machine(job.machine)
332 if not job.machine_idx:
showard71b94312009-08-20 23:40:02 +0000333 job.machine_idx = self.insert_machine(job, commit=commit)
334 else:
335 self.update_machine_information(job, commit=commit)
336
jamesrena12b8a02010-06-16 23:28:23 +0000337 afe_job_id = utils.get_afe_job_id(tag)
showardc1c1caf2009-09-08 16:26:50 +0000338
showard0fec8a02009-12-04 01:19:54 +0000339 data = {'tag':tag,
340 'label': job.label,
341 'username': job.user,
342 'machine_idx': job.machine_idx,
343 'queued_time': job.queued_time,
344 'started_time': job.started_time,
345 'finished_time': job.finished_time,
346 'afe_job_id': afe_job_id}
347 is_update = hasattr(job, 'index')
348 if is_update:
showardeab66ce2009-12-23 00:03:56 +0000349 self.update('tko_jobs', data, {'job_idx': job.index}, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000350 else:
showardeab66ce2009-12-23 00:03:56 +0000351 self.insert('tko_jobs', data, commit=commit)
showard0fec8a02009-12-04 01:19:54 +0000352 job.index = self.get_last_autonumber_value()
showardc1a98d12010-01-15 00:22:22 +0000353 self.update_job_keyvals(job, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000354 for test in job.tests:
355 self.insert_test(job, test, commit=commit)
apw7a7316b2008-02-21 17:42:05 +0000356
mbligh237bed32007-09-05 13:05:57 +0000357
showardc1a98d12010-01-15 00:22:22 +0000358 def update_job_keyvals(self, job, commit=None):
359 for key, value in job.keyval_dict.iteritems():
360 where = {'job_id': job.index, 'key': key}
361 data = dict(where, value=value)
362 exists = self.select('id', 'tko_job_keyvals', where=where)
363
364 if exists:
365 self.update('tko_job_keyvals', data, where=where, commit=commit)
366 else:
367 self.insert('tko_job_keyvals', data, commit=commit)
368
369
jadmanski0afbb632008-06-06 21:10:57 +0000370 def insert_test(self, job, test, commit = None):
371 kver = self.insert_kernel(test.kernel, commit=commit)
372 data = {'job_idx':job.index, 'test':test.testname,
373 'subdir':test.subdir, 'kernel_idx':kver,
374 'status':self.status_idx[test.status],
375 'reason':test.reason, 'machine_idx':job.machine_idx,
376 'started_time': test.started_time,
377 'finished_time':test.finished_time}
jadmanski9b6babf2009-04-21 17:57:40 +0000378 is_update = hasattr(test, "test_idx")
379 if is_update:
jadmanski74eebf32008-07-15 20:04:42 +0000380 test_idx = test.test_idx
showardeab66ce2009-12-23 00:03:56 +0000381 self.update('tko_tests', data,
382 {'test_idx': test_idx}, commit=commit)
jadmanskib591fba2008-09-10 16:19:22 +0000383 where = {'test_idx': test_idx}
showardeab66ce2009-12-23 00:03:56 +0000384 self.delete('tko_iteration_result', where)
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700385 self.delete('tko_iteration_perf_value', where)
showardeab66ce2009-12-23 00:03:56 +0000386 self.delete('tko_iteration_attributes', where)
showard0fec8a02009-12-04 01:19:54 +0000387 where['user_created'] = 0
showardeab66ce2009-12-23 00:03:56 +0000388 self.delete('tko_test_attributes', where)
jadmanski74eebf32008-07-15 20:04:42 +0000389 else:
showardeab66ce2009-12-23 00:03:56 +0000390 self.insert('tko_tests', data, commit=commit)
jadmanski74eebf32008-07-15 20:04:42 +0000391 test_idx = test.test_idx = self.get_last_autonumber_value()
392 data = {'test_idx': test_idx}
mbligh237bed32007-09-05 13:05:57 +0000393
jadmanski0afbb632008-06-06 21:10:57 +0000394 for i in test.iterations:
395 data['iteration'] = i.index
396 for key, value in i.attr_keyval.iteritems():
397 data['attribute'] = key
398 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000399 self.insert('tko_iteration_attributes', data,
jadmanski0afbb632008-06-06 21:10:57 +0000400 commit=commit)
401 for key, value in i.perf_keyval.iteritems():
402 data['attribute'] = key
403 data['value'] = value
showardeab66ce2009-12-23 00:03:56 +0000404 self.insert('tko_iteration_result', data,
mbligh432bad42007-10-09 19:56:07 +0000405 commit=commit)
mbligh056d0d32006-10-08 22:31:10 +0000406
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700407 data = {'test_idx': test_idx}
408 for i in test.perf_values:
409 data['iteration'] = i.index
410 for perf_dict in i.perf_measurements:
411 data['description'] = perf_dict['description']
412 data['value'] = perf_dict['value']
413 data['stddev'] = perf_dict['stddev']
414 data['units'] = perf_dict['units']
415 data['higher_is_better'] = perf_dict['higher_is_better']
Fang Deng7f24f0b2013-11-12 11:22:16 -0800416 data['graph'] = perf_dict['graph']
Dennis Jeffrey368c54b2013-07-24 11:19:03 -0700417 self.insert('tko_iteration_perf_value', data, commit=commit)
418
jadmanski0afbb632008-06-06 21:10:57 +0000419 for key, value in test.attributes.iteritems():
420 data = {'test_idx': test_idx, 'attribute': key,
421 'value': value}
showardeab66ce2009-12-23 00:03:56 +0000422 self.insert('tko_test_attributes', data, commit=commit)
mbligh2bd48872007-09-20 18:32:25 +0000423
jadmanski9b6babf2009-04-21 17:57:40 +0000424 if not is_update:
425 for label_index in test.labels:
426 data = {'test_id': test_idx, 'testlabel_id': label_index}
showardeab66ce2009-12-23 00:03:56 +0000427 self.insert('tko_test_labels_tests', data, commit=commit)
jadmanski9b6babf2009-04-21 17:57:40 +0000428
mbligh056d0d32006-10-08 22:31:10 +0000429
jadmanski0afbb632008-06-06 21:10:57 +0000430 def read_machine_map(self):
showard71b94312009-08-20 23:40:02 +0000431 if self.machine_group or not self.machine_map:
432 return
jadmanski0afbb632008-06-06 21:10:57 +0000433 for line in open(self.machine_map, 'r').readlines():
434 (machine, group) = line.split()
435 self.machine_group[machine] = group
mbligh96b9a5a2007-11-24 19:32:20 +0000436
437
showard71b94312009-08-20 23:40:02 +0000438 def machine_info_dict(self, job):
jadmanski0afbb632008-06-06 21:10:57 +0000439 hostname = job.machine
showard71b94312009-08-20 23:40:02 +0000440 group = job.machine_group
441 owner = job.machine_owner
jadmanski0afbb632008-06-06 21:10:57 +0000442
443 if not group:
showard71b94312009-08-20 23:40:02 +0000444 self.read_machine_map()
jadmanski0afbb632008-06-06 21:10:57 +0000445 group = self.machine_group.get(hostname, hostname)
showard71b94312009-08-20 23:40:02 +0000446 if group == hostname and owner:
447 group = owner + '/' + hostname
jadmanski0afbb632008-06-06 21:10:57 +0000448
showard71b94312009-08-20 23:40:02 +0000449 return {'hostname': hostname, 'machine_group': group, 'owner': owner}
450
451
452 def insert_machine(self, job, commit = None):
453 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000454 self.insert('tko_machines', machine_info, commit=commit)
jadmanski0afbb632008-06-06 21:10:57 +0000455 return self.get_last_autonumber_value()
456
457
showard71b94312009-08-20 23:40:02 +0000458 def update_machine_information(self, job, commit = None):
459 machine_info = self.machine_info_dict(job)
showardeab66ce2009-12-23 00:03:56 +0000460 self.update('tko_machines', machine_info,
showard71b94312009-08-20 23:40:02 +0000461 where={'hostname': machine_info['hostname']},
462 commit=commit)
463
464
jadmanski0afbb632008-06-06 21:10:57 +0000465 def lookup_machine(self, hostname):
466 where = { 'hostname' : hostname }
showardeab66ce2009-12-23 00:03:56 +0000467 rows = self.select('machine_idx', 'tko_machines', where)
jadmanski0afbb632008-06-06 21:10:57 +0000468 if rows:
469 return rows[0][0]
470 else:
471 return None
472
473
474 def lookup_kernel(self, kernel):
showardeab66ce2009-12-23 00:03:56 +0000475 rows = self.select('kernel_idx', 'tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000476 {'kernel_hash':kernel.kernel_hash})
477 if rows:
478 return rows[0][0]
479 else:
480 return None
481
482
483 def insert_kernel(self, kernel, commit = None):
484 kver = self.lookup_kernel(kernel)
485 if kver:
486 return kver
487
488 # If this kernel has any significant patches, append their hash
489 # as diferentiator.
490 printable = kernel.base
491 patch_count = 0
492 for patch in kernel.patches:
493 match = re.match(r'.*(-mm[0-9]+|-git[0-9]+)\.(bz2|gz)$',
494 patch.reference)
495 if not match:
496 patch_count += 1
497
showardeab66ce2009-12-23 00:03:56 +0000498 self.insert('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000499 {'base':kernel.base,
500 'kernel_hash':kernel.kernel_hash,
501 'printable':printable},
502 commit=commit)
503 kver = self.get_last_autonumber_value()
504
505 if patch_count > 0:
506 printable += ' p%d' % (kver)
showardeab66ce2009-12-23 00:03:56 +0000507 self.update('tko_kernels',
jadmanski0afbb632008-06-06 21:10:57 +0000508 {'printable':printable},
509 {'kernel_idx':kver})
510
511 for patch in kernel.patches:
512 self.insert_patch(kver, patch, commit=commit)
513 return kver
514
515
516 def insert_patch(self, kver, patch, commit = None):
517 print patch.reference
518 name = os.path.basename(patch.reference)[:80]
showardeab66ce2009-12-23 00:03:56 +0000519 self.insert('tko_patches',
jadmanski0afbb632008-06-06 21:10:57 +0000520 {'kernel_idx': kver,
521 'name':name,
522 'url':patch.reference,
523 'hash':patch.hash},
524 commit=commit)
525
526
jadmanski74eebf32008-07-15 20:04:42 +0000527 def find_test(self, job_idx, testname, subdir):
528 where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir}
showardeab66ce2009-12-23 00:03:56 +0000529 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000530 if rows:
531 return rows[0][0]
532 else:
533 return None
534
535
536 def find_tests(self, job_idx):
537 where = { 'job_idx':job_idx }
showardeab66ce2009-12-23 00:03:56 +0000538 rows = self.select('test_idx', 'tko_tests', where)
jadmanski0afbb632008-06-06 21:10:57 +0000539 if rows:
540 return [row[0] for row in rows]
541 else:
542 return []
543
544
545 def find_job(self, tag):
showardeab66ce2009-12-23 00:03:56 +0000546 rows = self.select('job_idx', 'tko_jobs', {'tag': tag})
jadmanski0afbb632008-06-06 21:10:57 +0000547 if rows:
548 return rows[0][0]
549 else:
550 return None
mblighaf25f062007-12-03 17:48:35 +0000551
552
mbligh96cf0512008-04-17 15:25:38 +0000553def _get_db_type():
jadmanski0afbb632008-06-06 21:10:57 +0000554 """Get the database type name to use from the global config."""
Jakob Juelich3270e182014-10-13 10:00:43 -0700555 get_value = global_config.global_config.get_config_value
556 return "db_" + get_value("AUTOTEST_WEB", "global_db_type", default="mysql")
mblighaf25f062007-12-03 17:48:35 +0000557
mbligh96cf0512008-04-17 15:25:38 +0000558
559def _get_error_class(class_name):
jadmanski0afbb632008-06-06 21:10:57 +0000560 """Retrieves the appropriate error class by name from the database
561 module."""
562 db_module = __import__("autotest_lib.tko." + _get_db_type(),
563 globals(), locals(), ["driver"])
564 return getattr(db_module.driver, class_name)
mbligh96cf0512008-04-17 15:25:38 +0000565
566
567def db(*args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000568 """Creates an instance of the database class with the arguments
569 provided in args and dargs, using the database type specified by
570 the global configuration (defaulting to mysql)."""
571 db_type = _get_db_type()
572 db_module = __import__("autotest_lib.tko." + db_type, globals(),
573 locals(), [db_type])
574 db = getattr(db_module, db_type)(*args, **dargs)
575 return db