Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master
---------------------------------------------------------------
commit 3ca8a07387d89a930c67a7d53e4faa74e1d303ab
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Wed Sep 9 12:14:44 2015 +0200
[frontend][API] fixed tests and updated doc to reflect recent changes
---------------------------------------------------------------
.../coprs_frontend/coprs/logic/builds_logic.py | 10 +++++-
frontend/coprs_frontend/coprs/rest_api/common.py | 31 ++++++++++-------
.../coprs/rest_api/resources/build.py | 17 ++++++---
.../coprs/rest_api/resources/build_task.py | 7 +---
.../coprs_frontend/tests/test_api/test_build_r.py | 16 ++++----
...test_build_chroot_r.py => test_build_task_r.py} | 32 +++++++++---------
frontend/docs/api_2/source/Resources/build.rst | 29 ++++++++--------
.../docs/api_2/source/Resources/build_task.rst | 35 ++++++++++---------
frontend/docs/api_2/source/index.rst | 3 ++
9 files changed, 99 insertions(+), 81 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py
b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index 3992ed0..3082b5c 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -511,6 +511,15 @@ class BuildsLogic(object):
else:
return None
+ @classmethod
+ def filter_is_finished(cls, query, is_finished):
+ # todo: check that ended_on is set correctly for all cases
+ # e.g.: failed dist-git import, cancellation
+ if is_finished:
+ return query.filter(models.Build.ended_on.isnot(None))
+ else:
+ return query.filter(models.Build.ended_on.is_(None))
+
class BuildChrootsLogic(object):
@classmethod
@@ -531,7 +540,6 @@ class BuildChrootsLogic(object):
.join(models.BuildChroot.mock_chroot)
.join(models.Build.copr)
.join(models.Copr.owner)
-
)
return query
diff --git a/frontend/coprs_frontend/coprs/rest_api/common.py
b/frontend/coprs_frontend/coprs/rest_api/common.py
index 7bc9c81..1945ce8 100644
--- a/frontend/coprs_frontend/coprs/rest_api/common.py
+++ b/frontend/coprs_frontend/coprs/rest_api/common.py
@@ -3,23 +3,23 @@ import base64
import datetime
import functools
from logging import getLogger
-from coprs.logic.builds_logic import BuildsLogic
-from coprs.logic.coprs_logic import CoprsLogic
-from coprs.rest_api.schemas import BuildTaskSchema
-from coprs.rest_api.util import mm_serialize_one, get_one_safe
-
-log = getLogger(__name__)
from flask import url_for
import flask
from .. import models
from ..logic.users_logic import UsersLogic
+from ..logic.builds_logic import BuildsLogic
+from ..logic.coprs_logic import CoprsLogic
+from ..rest_api.schemas import BuildTaskSchema
+from ..rest_api.util import mm_serialize_one, get_one_safe
from .exceptions import AuthFailed, ObjectNotFoundError
from .schemas import CoprChrootSchema, BuildSchema, ProjectSchema
from .util import mm_serialize_one
+log = getLogger(__name__)
+
def render_copr_chroot(chroot):
return {
@@ -41,21 +41,25 @@ def render_build(build, self_params=None):
"_links": {
"self": {"href": url_for(".buildr",
build_id=build.id, **self_params)},
"project": {"href": url_for(".projectr",
project_id=build.copr_id)},
- "tasks": {"href": url_for(".buildtasklistr",
build_id=build.id)}
+ "build_tasks": {"href":
url_for(".buildtasklistr", build_id=build.id)}
}
}
-def render_project(copr, self_params=None):
+def render_project(project, self_params=None):
+ """
+ :param models.Copr project:
+ """
if self_params is None:
self_params = {}
return {
- "project": mm_serialize_one(ProjectSchema, copr),
+ "project": mm_serialize_one(ProjectSchema, project),
"_links": {
- "self": {"href": url_for(".projectr",
project_id=copr.id, **self_params)},
- "builds": {"href": url_for(".buildlistr",
project_id=copr.id)},
- "chroots": {"href":
url_for(".projectchrootlistr", project_id=copr.id)}
+ "self": {"href": url_for(".projectr",
project_id=project.id, **self_params)},
+ "builds": {"href": url_for(".buildlistr",
project_id=project.id)},
+ "chroots": {"href":
url_for(".projectchrootlistr", project_id=project.id)},
+ "build_tasks":
{"href":url_for(".buildtasklistr", project_id=project.id) }
},
}
@@ -65,9 +69,10 @@ def render_build_task(chroot):
:type chroot: models.BuildChroot
"""
return {
- "task": mm_serialize_one(BuildTaskSchema, chroot),
+ "build_task": mm_serialize_one(BuildTaskSchema, chroot),
"_links": {
"project": {"href": url_for(".projectr",
project_id=chroot.build.copr_id)},
+ "build": {"href": url_for(".buildr",
build_id=chroot.build_id)},
"self": {"href": url_for(".buildtaskr",
build_id=chroot.build.id,
name=chroot.name)},
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build.py
b/frontend/coprs_frontend/coprs/rest_api/resources/build.py
index 7d31412..bc1605f 100644
--- a/frontend/coprs_frontend/coprs/rest_api/resources/build.py
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/build.py
@@ -27,7 +27,7 @@ class BuildListR(Resource):
parser.add_argument('limit', type=int)
parser.add_argument('offset', type=int)
- parser.add_argument('state', type=str)
+ parser.add_argument('is_finished', type=bool)
# parser.add_argument('package', type=str)
req_args = parser.parse_args()
@@ -41,6 +41,11 @@ class BuildListR(Resource):
else:
query = BuildsLogic.get_multiple()
+ if req_args["is_finished"] is not None:
+ is_finished = req_args["is_finished"]
+ query = BuildsLogic.filter_is_finished(query, is_finished)
+ # TODO: add test!
+
if req_args["limit"] is not None:
limit = req_args["limit"]
if limit <= 0 or limit > 100:
@@ -156,18 +161,18 @@ class BuildR(Resource):
def get(self, build_id):
parser = get_request_parser()
- parser.add_argument('show_chroots', type=bool, default=False)
+ parser.add_argument('show_build_tasks', type=bool, default=False)
req_args = parser.parse_args()
build = get_build_safe(build_id)
self_params = {}
- if req_args["show_chroots"]:
- self_params["show_chroots"] = req_args["show_chroots"]
+ if req_args["show_build_tasks"]:
+ self_params["show_build_tasks"] =
req_args["show_build_tasks"]
result = render_build(build, self_params)
- if req_args["show_chroots"]:
- result["build_chroots"] = [
+ if req_args["show_build_tasks"]:
+ result["build_tasks"] = [
render_build_task(chroot)
for chroot in build.build_chroots
]
diff --git a/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
b/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
index c17a1d1..4c2109c 100644
--- a/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
+++ b/frontend/coprs_frontend/coprs/rest_api/resources/build_task.py
@@ -24,11 +24,6 @@ from ..util import get_one_safe, get_request_parser
# resp.headers["Location"] == url_for(".buildtasklistr",
build_id=build_id)
-class BuildTaskListQuerySchema(Schema):
-
- build_id = fields.Int()
-
-
class BuildTaskListR(Resource):
state_choices = StatusEnum.vals.keys()
@@ -80,7 +75,7 @@ class BuildTaskListR(Resource):
build_chroots = query.all()
return {
- "tasks": [
+ "build_tasks": [
render_build_task(chroot)
for chroot in build_chroots
],
diff --git a/frontend/coprs_frontend/tests/test_api/test_build_r.py
b/frontend/coprs_frontend/tests/test_api/test_build_r.py
index 1f0075d..bcc5cf7 100644
--- a/frontend/coprs_frontend/tests/test_api/test_build_r.py
+++ b/frontend/coprs_frontend/tests/test_api/test_build_r.py
@@ -295,13 +295,13 @@ class TestBuildResource(CoprsTestCase):
assert build_obj["build"]["source_type"] ==
"srpm_upload"
- chroots_href =
build_obj["_links"]["chroots"]["href"]
- r2 = self.tc.get(chroots_href)
+ tasks_href =
build_obj["_links"]["build_tasks"]["href"]
+ r2 = self.tc.get(tasks_href)
build_chroots_obj = json.loads(r2.data)
- build_chroots_names = set([bc["chroot"]["name"] for bc in
- build_chroots_obj["chroots"]])
+ build_chroots_names = set([bc["build_task"]["chroot_name"]
for bc in
+ build_chroots_obj["build_tasks"]])
assert set(chroot_name_list) == build_chroots_names
- assert len(chroot_name_list) == len(build_chroots_obj["chroots"])
+ assert len(chroot_name_list) == len(build_chroots_obj["build_tasks"])
def test_post_multipart_missing_file(
self,f_users, f_coprs, f_builds, f_db,
@@ -351,20 +351,20 @@ class TestBuildResource(CoprsTestCase):
assert obj["build"]["id"] == b_id
assert obj["_links"]["self"]["href"] == href
- def test_get_one_build_with_chroots(self, f_users, f_coprs, f_builds, f_db,
+ def test_get_one_build_with_tasks(self, f_users, f_coprs, f_builds, f_db,
f_users_api, f_mock_chroots):
build_id_list = [b.id for b in self.basic_builds]
self.db.session.commit()
for b_id in build_id_list:
- href = "/api_2/builds/{}?show_chroots=True".format(b_id)
+ href = "/api_2/builds/{}?show_build_tasks=True".format(b_id)
r = self.tc.get(href)
assert r.status_code == 200
obj = json.loads(r.data)
assert obj["build"]["id"] == b_id
assert obj["_links"]["self"]["href"] == href
- assert "build_chroots" in obj
+ assert "build_tasks" in obj
def test_get_one_build_not_found(self, f_users, f_coprs, f_builds, f_db,
f_users_api, f_mock_chroots):
diff --git a/frontend/coprs_frontend/tests/test_api/test_build_chroot_r.py
b/frontend/coprs_frontend/tests/test_api/test_build_task_r.py
similarity index 75%
rename from frontend/coprs_frontend/tests/test_api/test_build_chroot_r.py
rename to frontend/coprs_frontend/tests/test_api/test_build_task_r.py
index 8b1b40a..253ed95 100644
--- a/frontend/coprs_frontend/tests/test_api/test_build_chroot_r.py
+++ b/frontend/coprs_frontend/tests/test_api/test_build_task_r.py
@@ -13,14 +13,12 @@ from coprs.logic.coprs_logic import CoprsLogic
from tests.coprs_test_case import CoprsTestCase, TransactionDecorator
-class TestBuildChrootResource(CoprsTestCase):
+class TestBuildTaskResource(CoprsTestCase):
def test_collection_ok(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db,
f_users_api):
- # project_id = self.c1.id
- # import ipdb; ipdb.set_trace()
- href = "/api_2/builds/1/chroots"
+ href = "/api_2/build_tasks?build_id=1&limit=5"
bc_list = copy.deepcopy(self.b1_bc)
self.db.session.commit()
@@ -28,14 +26,14 @@ class TestBuildChrootResource(CoprsTestCase):
r0 = self.tc.get(href)
assert r0.status_code == 200
obj = json.loads(r0.data)
- assert len(obj["chroots"]) == len(bc_list)
+ assert len(obj["build_tasks"]) == len(bc_list)
assert obj["_links"]["self"]["href"] == href
def test_post_not_allowed(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db,
f_users_api):
self.db.session.commit()
r0 = self.request_rest_api_with_auth(
- "/api_2/builds/1/chroots",
+ "/api_2/build_tasks",
method="post",
content={},
)
@@ -44,30 +42,32 @@ class TestBuildChrootResource(CoprsTestCase):
def test_get_one(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db,
f_users_api):
expected_fields = [
- "state",
- "git_hash",
- "started_on",
- "ended_on",
- "name"
+ ("state", None),
+ ("git_hash", None),
+ ("started_on", None),
+ ("ended_on", None),
+ ("name", "chroot_name"),
]
bc = self.b1_bc[0]
expected_dict = {
f: getattr(bc, f)
- for f in expected_fields
+ for f, _ in expected_fields
}
- href = "/api_2/builds/1/chroots/{}".format(bc.name)
+ href = "/api_2/build_tasks/1/{}".format(bc.name)
self.db.session.commit()
r0 = self.tc.get(href)
assert r0.status_code == 200
obj = json.loads(r0.data)
- for k in expected_fields:
- assert obj["chroot"][k] == expected_dict[k]
+ for k, res_k in expected_fields:
+ if res_k is None:
+ res_k = k
+ assert obj["build_task"][res_k] == expected_dict[k]
def test_get_one_bad_name(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db,
f_users_api):
- href = "/api_2/builds/1/chroots/surely_bad_chroot_name"
+ href = "/api_2/build_tasks/1/surely_bad_chroot_name"
self.db.session.commit()
r0 = self.tc.get(href)
diff --git a/frontend/docs/api_2/source/Resources/build.rst
b/frontend/docs/api_2/source/Resources/build.rst
index 3769808..517df70 100644
--- a/frontend/docs/api_2/source/Resources/build.rst
+++ b/frontend/docs/api_2/source/Resources/build.rst
@@ -4,7 +4,7 @@ Build
Build resources allows to submit new builds and access current build progress.
Build in fact consists of the few tasks, one per chroot, and detail information
-is available through sub-resource :doc:`./build_chroot`.
+is available through sub-resource :doc:`./build_task`.
@@ -47,10 +47,10 @@ Build fields
Field Type Description
================== ==================== ===============
id int unique build identifier
-state string current state of the build, value is aggregated
from build chroots
+state string current state of the build, value is aggregated
from build tasks
submitted_on int(unixtime UTC) time of the build submission
-started_on int(unixtime UTC) time when the first build chroot started,
otherwise ``null``
-ended_on int(unixtime UTC) time when the last build chroot ended, otherwise
``null``
+started_on int(unixtime UTC) time when the first build task started,
otherwise ``null``
+ended_on int(unixtime UTC) time when the last build task ended, otherwise
``null``
source_type string method used for build creation
source_metadata json object build source information
package_version string version of the source package
@@ -108,8 +108,8 @@ List builds
"self": {
"href": "/api_2/builds/106897"
},
- "chroots": {
- "href": "/api_2/builds/106897/chroots"
+ "build_tasks": {
+ "href": "/api_2/build_tasks?build_id=106897"
}
},
"build": {
@@ -269,7 +269,7 @@ Get build details
Returns details about build
:param int build_id: a unique identifier of the build
- :query bool show_chroots: embed :doc:`./build_chroot` sub-resources into the result,
default is False
+ :query bool show_build_tasks: embed :doc:`./build_task` sub-resources into the
result, default is False
:statuscode 200: no error
:statuscode 404: build not found
@@ -278,7 +278,7 @@ Get build details
.. sourcecode:: http
- GET /api_2/builds/106897 HTTP/1.1
+ GET /api_2/builds/106897?show_build_tasks=True HTTP/1.1
Host:
copr.fedoraproject.org
**Response**
@@ -289,10 +289,11 @@ Get build details
Content-Type: application/json
{
- "build_chroots": [
+ "build_tasks": [
{
- "chroot": {
- "name": "fedora-21-i386",
+ "tasks": {
+ "build_id": 3985,
+ "chroot_name": "fedora-21-i386",
"started_on": 1441366860,
"state": "succeeded",
"ended_on": 1441366969,
@@ -304,7 +305,7 @@ Get build details
"href": "/api_2/projects/3985"
},
"self": {
- "href":
"/api_2/builds/106897/chroots/fedora-21-i386"
+ "href": "/api_2/build_tasks/106897/fedora-21-i386"
}
}
}
@@ -316,8 +317,8 @@ Get build details
"self": {
"href": "/api_2/builds/106897?show_chroots=True"
},
- "chroots": {
- "href": "/api_2/builds/106897/chroots"
+ "build_tasks": {
+ "href": "/api_2/build_tasks/?build_id=3985"
}
},
"build": {
diff --git a/frontend/docs/api_2/source/Resources/build_task.rst
b/frontend/docs/api_2/source/Resources/build_task.rst
index c5871a4..2212475 100644
--- a/frontend/docs/api_2/source/Resources/build_task.rst
+++ b/frontend/docs/api_2/source/Resources/build_task.rst
@@ -1,7 +1,7 @@
Build Task
==========
-Build task represents information about individual build tasks per each chroot.
+Build task represents information about individual build tasks. One task is responsible
for one chroot.
Structure of the build task entity
----------------------------------
@@ -9,7 +9,7 @@ Structure of the build task entity
.. code-block:: javascript
{
- "name": "fedora-rawhide-x86_64",
+ "chroot_name": "fedora-rawhide-x86_64",
"build_id": 12345,
"started_on": 1440753865,
"ended_on": 1440753919,
@@ -18,14 +18,14 @@ Structure of the build task entity
"git_hash": "d241064b14f9dcd5d9032d0aca3b4e78fbd1aafd"
}
-Build chroot fields
-~~~~~~~~~~~~~~~~~~~
+Build tasks fields
+~~~~~~~~~~~~~~~~~~
================== ==================== ===============
Field Type Description
================== ==================== ===============
chroot_name str chroot name
build_id int unique build identifier
-state str current build state
+state str current build task state
started_on int(unixtime UTC) time when the build chroot started
ended_on int(unixtime UTC) time when the build chroot ended
git_hash str hash of the git commit in dist-git used for the
build
@@ -37,8 +37,8 @@ result_dir_url str(URL) location of the build results
Build Chroot doesn't currently support any modifications,
so all fields are read-only.
-List build chroots
-------------------
+List build tasks
+----------------
.. http:get:: /api_2/builds_tasks
@@ -77,10 +77,10 @@ List build chroots
Content-Type: application/json
{
- "chroots": [
+ "build_tasks": [
{
- "chroot": {
- "name": "fedora-rawhide-x86_64",
+ "build_task": {
+ "chroot_name": "fedora-rawhide-x86_64",
"started_on": 1440753865,
"state": "succeeded",
"ended_on": 1440753919,
@@ -92,14 +92,14 @@ List build chroots
"href": "/api_2/projects/3985"
},
"self": {
- "href":
"/api_2/builds/106882/chroots/fedora-rawhide-x86_64"
+ "href":
"/api_2/build_tasks/106882/fedora-rawhide-x86_64"
}
}
}
],
"_links": {
"self": {
- "href": "/api_2/builds/106882/chroots"
+ "href": "/api_2/build_tasks?build_id=106882"
}
}
}
@@ -109,7 +109,7 @@ List build chroots
Get build task details
----------------------
-.. http:get:: /api_2/builds/(int:build_id)/chroots/(str:name)
+.. http:get:: /api_2/build_tasks/(int:build_id)/(str:name)
Returns details about one build task
@@ -123,7 +123,7 @@ Get build task details
.. sourcecode:: http
- GET /api_2/builds/106882/chroots/fedora-rawhide-x86_64 HTTP/1.1
+ GET /api_2/build_tasks/106882/fedora-rawhide-x86_64 HTTP/1.1
Host:
copr.fedoraproject.org
**Response**
@@ -134,8 +134,9 @@ Get build task details
Content-Type: application/json
{
- "chroot": {
- "name": "fedora-rawhide-x86_64",
+ "build_task": {
+ "chroot_name": "fedora-rawhide-x86_64",
+ "build_id": 3985,
"started_on": 1440753865,
"state": "succeeded",
"ended_on": 1440753919,
@@ -147,7 +148,7 @@ Get build task details
"href": "/api_2/projects/3985"
},
"self": {
- "href":
"/api_2/builds/106882/chroots/fedora-rawhide-x86_64"
+ "href":
"/api_2/build_tasks/106882/fedora-rawhide-x86_64"
}
}
}
diff --git a/frontend/docs/api_2/source/index.rst b/frontend/docs/api_2/source/index.rst
index 3ed6a68..6bf0743 100644
--- a/frontend/docs/api_2/source/index.rst
+++ b/frontend/docs/api_2/source/index.rst
@@ -52,6 +52,9 @@ Here is a short example with the content of API root:
"builds": {
"href": "/api_2/builds"
}
+ "build_tasks": {
+ "href": "/api_2/build_tasks"
+ }
}
Response structure