Add rings api and start some requests api with tests.

This commit is contained in:
Tomáš Chvátal 2014-02-10 13:24:49 +01:00
parent dae106f849
commit 94f68ca8ef
7 changed files with 480 additions and 13 deletions

View File

@ -21,22 +21,150 @@ def _print_version(self):
print '%s'%(self.OSC_STAGING_VERSION)
quit(0)
def list_staging_projects(apiurl):
class StagingApi(object):
"""
List all current running staging projects
:param apiurl: url to the OBS api
:return list of known staging projects
Class containing various api calls to work with staging projects.
"""
projects = []
rings = ['openSUSE:Factory:Build',
'openSUSE:Factory:Core',
'openSUSE:Factory:MainDesktops',
'openSUSE:Factory:DVD']
ring_packages = dict()
apiurl = ""
url = makeurl(apiurl, ['search', 'project', 'id?match=starts-with(@name,\'openSUSE:Factory:Staging:\')'])
projxml = http_GET(url)
def __init__(self, apiurl):
"""
Initialize global variables
"""
self.apiurl = apiurl
self.ring_packages = self._generate_ring_packages()
def _generate_ring_packages(self):
"""
Generate dictionary with names of the rings
:return dictionary with ring names
"""
ret = dict()
for prj in self.rings:
url = makeurl(self.apiurl, ['source', prj])
root = http_GET(url)
for entry in ET.parse(root).getroot().findall('entry'):
ret[entry.attrib['name']] = prj
return ret
def get_staging_projects(self):
"""
Get all current running staging projects
:return list of known staging projects
"""
projects = []
url = makeurl(self.apiurl, ['search', 'project', 'id?match=starts-with(@name,\'openSUSE:Factory:Staging:\')'])
projxml = http_GET(url)
root = ET.parse(projxml).getroot()
for val in root.findall('project'):
projects.append(val.get('name'))
return projects
def staging_change_review_state(self, id, newstate, message):
"""
Change review state of the staging request
:param id: id of the request
:param newstate: state of the new request
:param message: message for the review
"""
""" taken from osc/osc/core.py, improved:
- verbose option added,
- empty by_user=& removed.
- numeric id can be int().
"""
query = {'cmd': 'changereviewstate',
'newstate': newstate,
'by_group': 'factory-staging',
'comment': message}
u = makeurl(self.apiurl, ['request', str(id)], query=query)
f = http_POST(u, data=message)
root = ET.parse(f).getroot()
return root.attrib['code']
def consolidate_review_request(self, request):
"""
Accept review of requests that are not yet in
any ring so we don't delay their testing.
:param request: request to check
"""
# FIXME: move this to activity class from api
# FIXME: verify the state of the submission not just the ring
# Consolidate all data from request
request_id = int(request.get('id'))
action = request.findall('action')
if not action:
raise oscerr.WrongArgs('Request {0} has no action'.format(request_id))
# we care only about first action
action = action[0]
# Where are we targeting the package
target_project = action.find('target').get('project')
target_package = action.find('target').get('package')
# If the values are empty it is no error
if not target_project or not target_pacakge:
e.append('no target/package in request {0}, action {1}; '.format(id, action))
# Verify the package ring
ring = self.ring_packages.get(tpkg, None)
if ring is None or ring == 'openSUSE:Factory:DVD' or ring == 'openSUSE:Factory:MainDesktops':
# accept the request here
message = "No need for staging, not in tested ring project"
self.staging_change_review_state(request_id, 'accepted', message)
def get_open_requests(self):
"""
Get all requests with open review for staging project
that are not yet included in any staging project
:return list of pending open review requests
"""
requests = []
# xpath query, using the -m, -r, -s options
where = "@by_group='factory-staging'+and+@state='new'"
url = makeurl(self.apiurl, ['search','request'], "match=state/@name='review'+and+review["+where+"]")
f = http_GET(url)
root = ET.parse(f).getroot()
for rq in root.findall('request'):
requests.append(rq)
return requests
def dispatch_open_requests(self):
"""
Verify all requests and dispatch them to staging projects or approve them
"""
# get all current pending requests
requests = self.get_open_requests()
# check if we can reduce it down by accepting some
for rq in requests:
self.consolidate_review_request(rq)
# FIXME: dispatch to various staging projects automatically
root = ET.parse(projxml).getroot()
for val in root.findall('project'):
projects.append(val.get('name'))
return projects
def _get_parent(apirul, project, repo = "standard"):
"""

View File

@ -8,6 +8,11 @@ import os
import contextlib
import unittest
import httpretty
# mock is part of python3.3
try:
import unittest.mock
except ImportError:
import mock
import oscs
import osc
@ -49,6 +54,34 @@ class TestApiCalls(unittest.TestCase):
override_no_gnome_keyring=True)
os.environ['OSC_CONFIG'] = oscrc
@httpretty.activate
def test_ring_packages(self):
"""
Validate the creation of the rings.
"""
# our content in the XML files
ring_packages = {'AGGR-antlr': 'openSUSE:Factory:MainDesktops',
'Botan': 'openSUSE:Factory:DVD',
'DirectFB': 'openSUSE:Factory:Core',
'zlib': 'openSUSE:Factory:Build'}
# Initiate the pretty overrides
self._register_pretty_url_get('http://localhost/source/openSUSE:Factory:Build',
'build-project.xml')
self._register_pretty_url_get('http://localhost/source/openSUSE:Factory:Core',
'core-project.xml')
self._register_pretty_url_get('http://localhost/source/openSUSE:Factory:MainDesktops',
'maindesktops-project.xml')
self._register_pretty_url_get('http://localhost/source/openSUSE:Factory:DVD',
'dvd-project.xml')
# Create the api object
api = oscs.StagingApi('http://localhost')
self.assertEqual(ring_packages,
api.ring_packages)
@httpretty.activate
def test_list_projects(self):
"""
@ -61,10 +94,49 @@ class TestApiCalls(unittest.TestCase):
'openSUSE:Factory:Staging:D'
]
# Initiate the pretty overrides
self._register_pretty_url_get('http://localhost/search/project/id?match=starts-with(@name,\'openSUSE:Factory:Staging:\')',
'staging-project-list.xml')
# Ensure the output is equal to what we expect
# Initiate the api with mocked rings
with mock_generate_ring_packages():
api = oscs.StagingApi('http://localhost')
# Compare the results
self.assertEqual(prjlist,
oscs.list_staging_projects('http://localhost'))
api.get_staging_projects())
@httpretty.activate
def test_open_requests(self):
"""
List projects and their content
"""
requests = [
]
# Initiate the pretty overrides
self._register_pretty_url_get('http://localhost/search/request?match=state/@name=\'review\'+and+review[@by_group=\'factory-staging\'+and+@state=\'new\']',
'open-requests.xml')
# Initiate the api with mocked rings
with mock_generate_ring_packages():
api = oscs.StagingApi('http://localhost')
# get the open requests
requests = api.get_open_requests()
count = len(requests)
# Compare the results, we only care now that we got 2 of them not the content
self.assertEqual(2, count)
# Here place all mockable functions
@contextlib.contextmanager
def mock_generate_ring_packages():
with mock.patch('oscs.StagingApi._generate_ring_packages', return_value={'AGGR-antlr': 'openSUSE:Factory:MainDesktops',
'Botan': 'openSUSE:Factory:DVD',
'DirectFB': 'openSUSE:Factory:Core',
'zlib': 'openSUSE:Factory:Build'}):
yield

3
tests/fixtures/build-project.xml vendored Normal file
View File

@ -0,0 +1,3 @@
<directory count='1'>
<entry name="zlib"/>
</directory>

3
tests/fixtures/core-project.xml vendored Normal file
View File

@ -0,0 +1,3 @@
<directory count='1'>
<entry name="DirectFB"/>
</directory>

3
tests/fixtures/dvd-project.xml vendored Normal file
View File

@ -0,0 +1,3 @@
<directory count='1'>
<entry name="Botan"/>
</directory>

View File

@ -0,0 +1,3 @@
<directory count='1'>
<entry name="AGGR-antlr"/>
</directory>

255
tests/fixtures/open-requests.xml vendored Normal file
View File

@ -0,0 +1,255 @@
<collection matches="2">
<request id="220956">
<action type="submit">
<source project="devel:languages:python:Factory" package="python3" rev="125"/>
<target project="openSUSE:Factory" package="python3"/>
</action>
<state name="review" who="factory-auto" when="2014-02-05T10:13:08">
<comment>Check Staging Project</comment>
</state>
<review state="accepted" when="2014-02-05T10:09:55" who="licensedigger" by_group="legal-auto">
<comment>{"approve": "preliminary, version number changed"} &lt;!-- {
"dest": {
"ldb": {
"prodonly": "",
"review": "done",
"rpm_license": "{\"python3.spec\":{\"curses\":[\"Python-2.0\"],\"python3\":[\"Python-2.0\"],\"dbm\":[\"Python-2.0\"],\"tk\":[\"Python-2.0\"]},\"python3-base.spec\":{\"-n python3-tools\":[\"Python-2.0\"],\"-n python3-idle\":[\"Python-2.0\"],\"python3-base\":[\"Python-2.0\"],\"-n python3-testsuite\":[\"Python-2.0\"],\"-n libpython%{so_version}\":[\"Python-2.0\"],\"-n python3-devel\":[\"Python-2.0\"]},\"python3-doc.spec\":{\"python3-doc\":[\"Python-2.0\"],\"pdf\":[\"Python-2.0\"]}}",
"status": "production",
"version": "3.3.3"
},
"license": {
"python3-base.spec": {
"-n libpython%{so_version}": [
"Python-2.0"
],
"-n python3-devel": [
"Python-2.0"
],
"-n python3-idle": [
"Python-2.0"
],
"-n python3-testsuite": [
"Python-2.0"
],
"-n python3-tools": [
"Python-2.0"
],
"python3-base": [
"Python-2.0"
]
},
"python3-doc.spec": {
"pdf": [
"Python-2.0"
],
"python3-doc": [
"Python-2.0"
]
},
"python3.spec": {
"curses": [
"Python-2.0"
],
"dbm": [
"Python-2.0"
],
"python3": [
"Python-2.0"
],
"tk": [
"Python-2.0"
]
}
},
"version": "3.3.3"
},
"hint": [
"version changed: src('3.3.3') differs from dest('3.4.0~b3')"
],
"plugin": "0.60",
"src": {
"auto-co": "/api.opensuse.org/devel:languages:python:Factory/python3%3.4.0~b3%r125",
"kiwi_only": false,
"license": {
"python3-base.spec": {
"-n libpython%{so_version}": [
"Python-2.0"
],
"-n python3-devel": [
"Python-2.0"
],
"-n python3-idle": [
"Python-2.0"
],
"-n python3-testsuite": [
"Python-2.0"
],
"-n python3-tools": [
"Python-2.0"
],
"python3-base": [
"Python-2.0"
]
},
"python3-doc.spec": {
"pdf": [
"Python-2.0"
],
"python3-doc": [
"Python-2.0"
]
},
"python3.spec": {
"curses": [
"Python-2.0"
],
"dbm": [
"Python-2.0"
],
"python3": [
"Python-2.0"
],
"tk": [
"Python-2.0"
]
}
},
"rev": "125",
"version": "3.4.0~b3",
"version_diff": "src('3.3.3') differs from dest('3.4.0~b3')"
}
} --&gt;</comment>
</review>
<review state="accepted" when="2014-02-05T10:09:55" who="factory-auto" by_group="factory-auto">
<comment>Check script succeeded</comment>
</review>
<review state="accepted" when="2014-02-05T10:13:07" who="a_jaeger" by_group="opensuse-review-team">
<comment>ok</comment>
</review>
<review state="accepted" when="2014-02-05T10:13:08" who="factory-repo-checker" by_user="factory-repo-checker">
<comment>Builds for repo openSUSE_Factory</comment>
</review>
<review state="new" by_group="factory-staging">
<comment>Check Staging Project</comment>
</review>
<history name="review" who="saschpe" when="2014-02-05T10:09:55"/>
<history name="review" who="factory-auto" when="2014-02-05T10:13:07">
<comment>Please review sources</comment>
</history>
<history name="review" who="factory-auto" when="2014-02-05T10:13:08">
<comment>Please review build success</comment>
</history>
<description>- initial commit of 3.4.0 beta 3
* new stdlib modules: pathlib, enum, statistics, tracemalloc
* asynchronous IO with new asyncio module
* introspection data for builtins
* subprocesses no longer inherit open file descriptors
* standardized metadata for packages
* internal hashing changed to SipHash
* new pickle protocol
* improved handling of codecs
* TLS 1.2 support
* major speed improvements for internal unicode handling
* many bugfixes and optimizations
- see porting guide at:
http://docs.python.org/3.4/whatsnew/3.4.html#porting-to-python-3-4
- moved several modules to -testsuite subpackage
- updated list of binary extensions, refreshed patches
- tracemalloc_gcov.patch fixes profile-based optimization build
- updated packages and pre_checkin.sh to use ~-version notation
for prereleases
- fix-shebangs part of build process moved to common %prep
- drop python-3.3.2-no-REUSEPORT.patch (upstreamed)
- update baselibs for new soname
- TODOs:
* require python-pip, make ensurepip work with zypper
- initial commit of 3.4.0 beta2
* for full changelog, see python3-base
- initial commit of 3.4.0 beta 3
* for full changelog, see python3-base</description>
</request>
<request id="221625">
<action type="submit">
<source project="X11:XOrg" package="xf86-video-intel" rev="110"/>
<target project="openSUSE:Factory" package="xf86-video-intel"/>
</action>
<state name="review" who="factory-auto" when="2014-02-10T12:03:29">
<comment>Check Staging Project</comment>
</state>
<review state="accepted" when="2014-02-10T12:00:13" who="licensedigger" by_group="legal-auto">
<comment>{"approve": "preliminary, version number changed"} &lt;!-- {
"dest": {
"ldb": {
"review": "never",
"rpm_license": "{\"xf86-video-intel.spec\":{\"xf86-video-intel\":[\"MIT\"]}}",
"status": "production",
"version": "2.99.909"
},
"license": {
"xf86-video-intel.spec": {
"xf86-video-intel": [
"MIT"
]
}
},
"version": "2.99.909"
},
"hint": [
"no ldb.risk defined, okay as per bnc#771677. ",
"ldb.review was (apparently) never done"
],
"plugin": "0.60",
"src": {
"auto-co": "/api.opensuse.org/X11:XOrg/xf86-video-intel%2.99.910%r110",
"kiwi_only": false,
"license": {
"xf86-video-intel.spec": {
"xf86-video-intel": [
"MIT"
]
}
},
"rev": "110",
"version": "2.99.910",
"version_diff": null
}
} --&gt;</comment>
</review>
<review state="accepted" when="2014-02-10T12:00:13" who="factory-auto" by_group="factory-auto">
<comment>Check script succeeded</comment>
</review>
<review state="new" by_group="opensuse-review-team">
<comment>Please review sources</comment>
</review>
<review state="new" by_user="factory-repo-checker">
<comment>Please review build success</comment>
</review>
<review state="new" by_group="factory-staging">
<comment>Check Staging Project</comment>
</review>
<history name="review" who="sndirsch" when="2014-02-10T12:00:13"/>
<history name="review" who="factory-auto" when="2014-02-10T12:03:28">
<comment>Please review sources</comment>
</history>
<history name="review" who="factory-auto" when="2014-02-10T12:03:29">
<comment>Please review build success</comment>
</history>
<description>- Update to 3.0 prerelease 2.99.910
* Only discard damage when overwriting the dirty CPU bo, instead
of discarding damage that will be shown!
* Reset operation state when switching between glyph caches.
https://bugs.freedesktop.org/show_bug.cgi?id=74494
* Fully reinitialise pixmaps allocated from the freed cache. Fixes
a potential issue (crash or misrendering) when using some compositors.
https://bugs.freedesktop.org/show_bug.cgi?id=74550
* Do not expose the TexturedVideo adaptor in UXA when it is disabled
either due to a hung GPU or explicitly disabled by the user.
* Restore the pipe stall when changing CC state on gen6, otherwise
the GPU may not flush intermediate results from all EU resulting
in render corruption (usually the occasional black box).
Regression from 2.99.906
https://bugs.freedesktop.org/show_bug.cgi?id=7237</description>
</request>
</collection>