1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#!/usr/bin/python
# uses the fedora.client library to talk to israwhidebroken
#
# Copyright 2009, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Author: Will Woods <wwoods@redhat.com>
from fedora.client import BaseClient, AppError, ServerError
import os, sys
# A couple of useful helper methods
def todays_compose_id(serial=1):
import datetime
'''Return the default compose_id for today'''
return int(datetime.datetime.today().strftime('%Y%m%d') + '%02u' % serial)
def treedata_from_url(url):
import urllib2, ConfigParser
import xml.etree.cElementTree as ElementTree
'''Given the URL of a rawhide tree, return a dict of tree data'''
treedata = dict()
# this one's a gimme
treedata['compose_id'] = todays_compose_id()
try:
# fetch treeinfo
treeinfo = ConfigParser.SafeConfigParser()
treeinfo.readfp(urllib2.urlopen(url+'/.treeinfo'))
treedata['arch'] = treeinfo.get('general','arch')
treedata['tree_time'] = int(float(treeinfo.get('general','timestamp')))
except:
pass
try:
# fetch repomd.xml
repomd = urllib2.urlopen(url+'/repodata/repomd.xml')
repomdtree = ElementTree.parse(repomd)
ns = '{http://linux.duke.edu/metadata/repo}'
revision = repomdtree.getroot().find(ns+'revision')
treedata['repodata_time'] = int(revision.text)
except:
pass
return treedata
# XXX TODO: if 'exc' in r: raise appropriate error?
class IRBClient(BaseClient):
def get_tests(self):
'''Returns a list of known tests'''
r = self.send_request('/get_tests')
return r.get('tests')
def get_trees(self, *args, **kw):
'''Get a list of trees that match all the given parameters:
id, compose_id, arch, tree_time, repodata_time'''
r = self.send_request('/get_trees', req_params=kw)
return r.get('trees')
def add_tree(self, *args, **kw):
'''Add a new tree to israwhidebroken.
Required arguments: arch, compose_id
Optional: tree_time, repodata_time
Returns the new tree.'''
for field in ('arch', 'compose_id', 'tree_time', 'repodata_time'):
if field not in kw:
raise ValueError, "Missing required arg %s" % field
if type(kw['arch']) is not str:
raise ValueError, 'arch must be str'
r = self.send_request('/add_tree', auth=True, req_params=kw)
return r.get('tree')
def update_tree(self, *args, **kw):
'''Add a new tree, or update an existing tree.
Required arguments: id, or arch and compose_id
Optional: tree_time, repodata_time
Returns the tree data.'''
if 'id' in kw:
treelist = self.get_trees(id=id)
else:
treelist = self.get_trees(arch=kw['arch'],
compose_id=kw['compose_id'])
if len(treelist) == 0:
return self.add_tree(*args, **kw)
kw['treeid'] = treelist[0]['id']
r = self.send_request('/update_tree', auth=True, req_params=kw)
return r.get('tree')
def add_result(self, treeid, testid, result, detail_url=None):
'''Add a test result to the database. Returns result id on success.'''
params = {'treeid':treeid, 'testid':testid, 'result': result}
if detail_url:
params['detail_url'] = detail_url
r = self.send_request('/add_result', auth=True, req_params=params)
return r.get('id')
def report_result(self, testid, tree_data, result, add_tree=False):
'''Convenience method that will look up the tree using tree_data and
then add the given result for the given testid.
tree_data should be a dict containing enough data to look up exactly
one tree. Typically that means either specifying the exact treeid if
it's already known (e.g. {'id':treeid}) or a dict with 'arch' and one or
more of (compose_id, tree_time, repodata_time)
If add_tree is True and tree_data does not match any known tree, a new
tree will be added.
Returns result id on success.'''
treelist = self.get_trees(**tree_data)
if not treelist:
if not add_tree:
print 'Could not find a matching tree'
return None
tree = self.add_tree(**tree_data)
# FIXME else check for error
elif len(treelist) > 1:
print 'Ambiguous tree data - too many matching trees'
return False
else:
tree = treelist.pop()
return self.add_result(treeid=tree['id'], testid=testid, result=result)
|