Split initial state machine to separate class
Move OBS simulation to separate class, should be eventually moved to separate file as well. And converted test_dispatch_open_requests to use new and shiny testing infrastructure.
This commit is contained in:
parent
ac1114b878
commit
dbb0632977
@ -32,17 +32,31 @@ if PY3:
|
||||
else:
|
||||
string_types = basestring,
|
||||
|
||||
class TestApiCalls(unittest.TestCase):
|
||||
class OBS:
|
||||
"""
|
||||
Tests for various api calls to ensure we return expected content
|
||||
Class trying to simulate a simple OBS
|
||||
"""
|
||||
responses = { 'GET': {}, 'PUT': {}, 'POST': {}, 'ALL': {} }
|
||||
responses = { }
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the configuration and create basic OBS instance
|
||||
"""
|
||||
|
||||
self.reset_config()
|
||||
|
||||
def reset_config(self):
|
||||
self._clear_responses()
|
||||
|
||||
def _clear_responses(self):
|
||||
"""
|
||||
Reset predefined responses
|
||||
"""
|
||||
self.responses = { 'GET': {}, 'PUT': {}, 'POST': {}, 'ALL': {} }
|
||||
# Add methods to manipulate reviews
|
||||
self._request_review()
|
||||
# Add methods to search requests
|
||||
self._request_search()
|
||||
|
||||
def _pretty_callback(self, request, uri, headers):
|
||||
"""
|
||||
@ -55,31 +69,147 @@ class TestApiCalls(unittest.TestCase):
|
||||
:param uri: uri as provided to callback function by HTTPretty
|
||||
:param headers: headers as provided to callback function by HTTPretty
|
||||
"""
|
||||
|
||||
# Get path
|
||||
path = re.match( r'.*localhost([^?]*)(\?.*)?',uri).group(1)
|
||||
reply = None
|
||||
# Try to find a fallback
|
||||
if self.responses['ALL'].has_key(path):
|
||||
reply = self.responses['ALL'][path]
|
||||
# Try to find a specific method
|
||||
if self.responses[request.method].has_key(path):
|
||||
reply = self.responses[request.method][path]
|
||||
# We have something to reply with
|
||||
if reply:
|
||||
# It's a list, so take the first
|
||||
if isinstance(reply, list):
|
||||
reply = reply.pop(0)
|
||||
# It's string
|
||||
if isinstance(reply, string_types):
|
||||
return (200, headers, reply)
|
||||
# It's XML
|
||||
if reply.startswith('<'):
|
||||
return (200, headers, reply)
|
||||
# It's fixture
|
||||
else:
|
||||
return (200, headers, _get_fixture_content(reply))
|
||||
# All is left is callback function
|
||||
else:
|
||||
return (200, headers, reply(self.responses, request, uri))
|
||||
# No possible response found
|
||||
else:
|
||||
if len(path) == 0:
|
||||
path = uri
|
||||
raise BaseException("No response for {0} on {1} provided".format(request.method,path))
|
||||
|
||||
def _register_pretty(self):
|
||||
# Initial request data
|
||||
requests_data = { '123': { 'request': 'new', 'review': 'accepted',
|
||||
'who': 'Admin', 'by': 'group', 'id': '123',
|
||||
'by_who': 'opensuse-review-team',
|
||||
'package': 'gcc' },
|
||||
'321': { 'request': 'review', 'review': 'new',
|
||||
'who': 'Admin', 'by': 'group', 'id': '321',
|
||||
'by_who': 'factory-staging',
|
||||
'package': 'puppet' }
|
||||
}
|
||||
|
||||
def _request_review(self):
|
||||
"""
|
||||
Register requests methods
|
||||
"""
|
||||
|
||||
# Load template
|
||||
tmpl = Template(self._get_fixture_content('request_review.xml'))
|
||||
|
||||
# What happens when we try to change the review
|
||||
def review_change(responses, request, uri):
|
||||
rq_id = re.match( r'.*/([0-9]+)',uri).group(1)
|
||||
args = self.requests_data[rq_id]
|
||||
# Adding review
|
||||
if request.querystring.has_key(u'cmd') and request.querystring[u'cmd'] == [u'addreview']:
|
||||
self.requests_data[rq_id]['request'] = 'review'
|
||||
self.requests_data[rq_id]['review'] = 'new'
|
||||
# Changing review
|
||||
if request.querystring.has_key(u'cmd') and request.querystring[u'cmd'] == [u'changereviewstate']:
|
||||
self.requests_data[rq_id]['request'] = 'new'
|
||||
self.requests_data[rq_id]['review'] = request.querystring[u'newstate'][0]
|
||||
# Project review
|
||||
if request.querystring.has_key(u'by_project'):
|
||||
self.requests_data[rq_id]['by'] = 'project'
|
||||
self.requests_data[rq_id]['by_who'] = request.querystring[u'by_project'][0]
|
||||
# Group review
|
||||
if request.querystring.has_key(u'by_group'):
|
||||
self.requests_data[rq_id]['by'] = 'group'
|
||||
self.requests_data[rq_id]['by_who'] = request.querystring[u'by_group'][0]
|
||||
responses['GET']['/request/' + rq_id] = tmpl.substitute(self.requests_data[rq_id])
|
||||
return responses['GET']['/request/' + rq_id]
|
||||
|
||||
# Register methods for all requests
|
||||
for rq in self.requests_data:
|
||||
self.responses['GET']['/request/' + rq] = tmpl.substitute(self.requests_data[rq])
|
||||
self.responses['ALL']['/request/' + rq] = review_change
|
||||
|
||||
def _request_search(self):
|
||||
"""
|
||||
Allows searching for requests
|
||||
"""
|
||||
def request_search(responses, request, uri):
|
||||
# Searching for requests that has open review for staging group
|
||||
if request.querystring.has_key(u'match') and request.querystring[u'match'][0] == u"state/@name='review' and review[@by_group='factory-staging' and @state='new']":
|
||||
rqs = []
|
||||
# Itereate through all requests
|
||||
for rq in self.requests_data:
|
||||
# Find the ones matching the condition
|
||||
if self.requests_data[rq]['request'] == 'review' and self.requests_data[rq]['review'] == 'new' and self.requests_data[rq]['by'] == 'group' and self.requests_data[rq]['by_who'] == 'factory-staging':
|
||||
rqs.append(rq)
|
||||
# Create response
|
||||
ret_str = '<collection matches="' + str(len(rqs)) + '">'
|
||||
for rq in rqs:
|
||||
ret_str += responses['GET']['/request/' + rq]
|
||||
ret_str += '</collection>'
|
||||
return ret_str
|
||||
# We are searching for something else, we don't know the answer
|
||||
raise BaseException("No search results defined for " + pprint.pformat(request.querystring))
|
||||
self.responses['GET']['/search/request'] = request_search
|
||||
|
||||
def register_obs(self):
|
||||
"""
|
||||
Register custom callback for HTTPretty
|
||||
"""
|
||||
httpretty.register_uri(httpretty.GET,re.compile(r'/.*localhost.*/'),body=self._pretty_callback)
|
||||
httpretty.register_uri(httpretty.PUT,re.compile(r'/.*localhost.*/'),body=self._pretty_callback)
|
||||
httpretty.register_uri(httpretty.POST,re.compile(r'/.*localhost.*/'),body=self._pretty_callback)
|
||||
self.reset_config()
|
||||
# Initiate the api with mocked rings
|
||||
with mock_generate_ring_packages():
|
||||
self.api = oscs.StagingAPI('http://localhost')
|
||||
|
||||
def _get_fixtures_dir(self):
|
||||
"""
|
||||
Return path for fixtures
|
||||
"""
|
||||
return os.path.join(os.getcwd(), 'tests/fixtures')
|
||||
|
||||
def _get_fixture_path(self, filename):
|
||||
"""
|
||||
Return path for fixture
|
||||
"""
|
||||
return os.path.join(self._get_fixtures_dir(), filename)
|
||||
|
||||
def _get_fixture_content(self, filename):
|
||||
"""
|
||||
Return content of fixture
|
||||
"""
|
||||
response = open(self._get_fixture_path(filename), 'r')
|
||||
content = response.read()
|
||||
response.close()
|
||||
return content
|
||||
|
||||
class TestApiCalls(unittest.TestCase):
|
||||
"""
|
||||
Tests for various api calls to ensure we return expected content
|
||||
"""
|
||||
|
||||
obs = OBS()
|
||||
|
||||
def _get_fixtures_dir(self):
|
||||
"""
|
||||
@ -165,22 +295,17 @@ class TestApiCalls(unittest.TestCase):
|
||||
Test dispatching and closure of non-ring packages
|
||||
"""
|
||||
|
||||
# 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')
|
||||
|
||||
# There should be just one request that gets closed
|
||||
# We don't care about the return so just reuse the above :P
|
||||
# If there is bug in the function we get assertion about closing more issues than we should
|
||||
self._register_pretty_url_post('http://localhost/request/220956?comment=No+need+for+staging%2C+not+in+tested+ring+project.&newstate=accepted&by_group=factory-staging&cmd=changereviewstate',
|
||||
'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.dispatch_open_requests()
|
||||
# Register OBS
|
||||
self.obs.register_obs()
|
||||
# Get rid of open requests
|
||||
self.obs.api.dispatch_open_requests()
|
||||
# Check that we tried to close it
|
||||
self.assertEqual(httpretty.last_request().method, 'POST')
|
||||
self.assertEqual(httpretty.last_request().querystring[u'cmd'], [u'changereviewstate'])
|
||||
# Try it again
|
||||
self.obs.api.dispatch_open_requests()
|
||||
# This time there should be nothing to close
|
||||
self.assertEqual(httpretty.last_request().method, 'GET')
|
||||
|
||||
@httpretty.activate
|
||||
def test_pseudometa_get_prj(self):
|
||||
@ -306,41 +431,25 @@ class TestApiCalls(unittest.TestCase):
|
||||
Test whether accepting/creating reviews behaves correctly
|
||||
"""
|
||||
|
||||
with mock_generate_ring_packages():
|
||||
api = oscs.StagingAPI('http://localhost')
|
||||
|
||||
tmpl = Template(self._get_fixture_content('request_review.xml'))
|
||||
|
||||
self._clear_responses()
|
||||
self.responses['GET']['/request/123'] = tmpl.substitute(request='new', review='accepted', review_project="openSUSE:Factory")
|
||||
|
||||
def review_change(responses, request, uri):
|
||||
if request.querystring.has_key(u'cmd') and request.querystring[u'cmd'] == [u'addreview']:
|
||||
responses['GET']['/request/123'] = tmpl.substitute(request='review', review='new', review_project=request.querystring[u'by_project'][0])
|
||||
if request.querystring.has_key(u'cmd') and request.querystring[u'cmd'] == [u'changereviewstate']:
|
||||
responses['GET']['/request/123'] = tmpl.substitute(request='new', review=request.querystring[u'newstate'][0], review_project=request.querystring[u'by_project'][0])
|
||||
return responses['GET']['/request/123']
|
||||
|
||||
self.responses['ALL']['/request/123'] = review_change
|
||||
|
||||
self._register_pretty()
|
||||
# Register OBS
|
||||
self.obs.register_obs()
|
||||
|
||||
# Add review
|
||||
api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.obs.api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.assertEqual(httpretty.last_request().method, 'POST')
|
||||
self.assertEqual(httpretty.last_request().querystring[u'cmd'], [u'addreview'])
|
||||
# Try to readd, should do anything
|
||||
api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.obs.api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.assertEqual(httpretty.last_request().method, 'GET')
|
||||
# Accept review
|
||||
api.set_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.obs.api.set_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.assertEqual(httpretty.last_request().method, 'POST')
|
||||
self.assertEqual(httpretty.last_request().querystring[u'cmd'], [u'changereviewstate'])
|
||||
# Try to accept it again should do anything
|
||||
api.set_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.obs.api.set_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.assertEqual(httpretty.last_request().method, 'GET')
|
||||
# But we should be able to reopen it
|
||||
api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.obs.api.add_review('123', 'openSUSE:Factory:Staging:A')
|
||||
self.assertEqual(httpretty.last_request().method, 'POST')
|
||||
self.assertEqual(httpretty.last_request().querystring[u'cmd'], [u'addreview'])
|
||||
|
||||
|
255
tests/fixtures/open-requests.xml
vendored
255
tests/fixtures/open-requests.xml
vendored
@ -1,255 +0,0 @@
|
||||
<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"} <!-- {
|
||||
"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')"
|
||||
}
|
||||
} --></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="elem-ring-0" rev="110"/>
|
||||
<target project="openSUSE:Factory" package="elem-ring-0"/>
|
||||
</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"} <!-- {
|
||||
"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
|
||||
}
|
||||
} --></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>
|
13
tests/fixtures/request_review.xml
vendored
13
tests/fixtures/request_review.xml
vendored
@ -1,14 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<request id="123">
|
||||
<request id="${id}">
|
||||
<action type="submit">
|
||||
<source project="home:Admin" package="puppet" rev="59f0f46262d7b57b9cdc720c06d5e317"/>
|
||||
<target project="openSUSE:Factory" package="puppet"/>
|
||||
<source project="home:Admin" package="${package}" rev="59f0f46262d7b57b9cdc720c06d5e317"/>
|
||||
<target project="openSUSE:Factory" package="${package}"/>
|
||||
</action>
|
||||
<state name="${request}" who="Admin" when="2014-02-17T12:38:52">
|
||||
<comment>Passed staging project "openSUSE:Factory:Staging:test"</comment>
|
||||
<comment>...</comment>
|
||||
</state>
|
||||
<review state="${review}" when="2014-02-17T12:34:10" who="Admin" by_project="${review_project}">
|
||||
<comment>Passed staging project "openSUSE:Factory:Staging:test"</comment>
|
||||
<review state="${review}" when="2014-02-17T12:34:10" who="${who}" by_${by}="${by_who}">
|
||||
<comment>...</comment>
|
||||
</review>
|
||||
<description>test</description>
|
||||
</request>
|
||||
|
Loading…
x
Reference in New Issue
Block a user