[copr] master's head updated: 1030493 - [cli] check that at least one chroot is entered (4ef718d)
by Miroslav Suchý
Repository : http://git.fedorahosted.org/cgit/copr.git
Branch 'master' now includes:
6e50c18 [backend] rework ip address extraction
decf413 [frontend] add missing json import
53636f3 [frontend] remove unused imports
702acd6 [frontend] fix name -> coprname typo
c943df9 [frontend] add StatusEnum
9d98de7 [frontend] add Build <-> Chroot relation
6aed00d [frontend] create BuildChroot objects on new build
8b1f906 [XXX] disable make check
d1cf74f [frontend] add ActionsLogic
8b1cdec [frontend] rewrite backend view to use Build <-> Chroot relation
359594d [frontend] skip legal-flag actions when dumping waiting actions
974d877 add migration script - add table build_chroot
acfc8e4 [spec] enable/disable test using variable
51df27a [tests]: fix test_build_logic to handle BuildChroot
7bf4240 fixup! [frontend] add ActionsLogic
0afe730 fixup! [tests]: fix test_build_logic to handle BuildChroot
a986c44 [frontend] typo
4ef718d 1030493 - [cli] check that at least one chroot is entered
10 years, 5 months
[copr] enter_the_matrix: [frontend]: add copr monitor (a0236f6)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit a0236f6f064582c97a21bc05b41f252a0b12efa6
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Thu Nov 14 16:58:55 2013 +0100
[frontend]: add copr monitor
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/models.py | 11 ++++++++
coprs_frontend/coprs/static/copr.css | 4 +++
coprs_frontend/coprs/templates/coprs/detail.html | 3 ++
.../coprs/templates/coprs/detail/monitor.html | 28 ++++++++++++++++++++
.../coprs/views/coprs_ns/coprs_general.py | 17 ++++++++++++
5 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 48cf8a0..e494c75 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -297,6 +297,17 @@ class BuildChroot(db.Model, Serializer):
build = db.relationship('Build', backref=db.backref('build_chroots'))
status = db.Column(db.Integer, default=helpers.StatusEnum('pending'))
+ @property
+ def name(self):
+ """ Textual representation of name of this chroot """
+ return self.mock_chroot.chroot_name
+
+ @property
+ def state(self):
+ """ Return text representation of status of this build chroot """
+ return helpers.StatusEnum(self.status)
+
+
class LegalFlag(db.Model, Serializer):
id = db.Column(db.Integer, primary_key=True)
diff --git a/coprs_frontend/coprs/static/copr.css b/coprs_frontend/coprs/static/copr.css
index 97e3510..451af8b 100644
--- a/coprs_frontend/coprs/static/copr.css
+++ b/coprs_frontend/coprs/static/copr.css
@@ -318,6 +318,10 @@ table.releases tr.release-end {
border-bottom: 3px solid #f2f2f2;
}
+table.monitor td {
+ padding: 0 20px;
+}
+
form.legal-flag, form.legal-flag input {
color: #888888;
margin-top: 5px;
diff --git a/coprs_frontend/coprs/templates/coprs/detail.html b/coprs_frontend/coprs/templates/coprs/detail.html
index 749ffb6..cc4535c 100644
--- a/coprs_frontend/coprs/templates/coprs/detail.html
+++ b/coprs_frontend/coprs/templates/coprs/detail.html
@@ -17,6 +17,9 @@
<li class="{% block builds_selected %}unselected{% endblock %}">
<a href="{{ url_for('coprs_ns.copr_builds', username = copr.owner.name, coprname = copr.name) }}">Builds</a>
</li>
+ <li class="{% block monitor_selected %}unselected{% endblock %}">
+ <a href="{{ url_for('coprs_ns.copr_build_monitor', username = copr.owner.name, coprname = copr.name) }}">Monitor</a>
+ </li>
{% if g.user and g.user.can_build_in(copr) %}
<li class="{% block new_build_selected %}unselected{% endblock %}">
<a href="{{ url_for('coprs_ns.copr_add_build', username = copr.owner.name, coprname = copr.name) }}">New Build</a>
diff --git a/coprs_frontend/coprs/templates/coprs/detail/monitor.html b/coprs_frontend/coprs/templates/coprs/detail/monitor.html
new file mode 100644
index 0000000..e936724
--- /dev/null
+++ b/coprs_frontend/coprs/templates/coprs/detail/monitor.html
@@ -0,0 +1,28 @@
+{% extends "coprs/detail.html" %}
+{% block title %}Monitor {{ copr.owner.name }}/{{ copr.name }}{% endblock %}
+{% block monitor_selected %}selected{% endblock %}
+
+{% block detail_body %}
+ {% if build %}
+ <p>
+ Latest build status:
+ <strong>{{ build.state }}</strong>
+ </p>
+ {% if not build.canceled %}
+ <table class="monitor">
+ <tr>
+ <th>Chroot</th>
+ <th>State</th>
+ </tr>
+ {% for chroot in build.build_chroots %}
+ <tr class="build-{{ chroot.state }}">
+ <td>{{ chroot.name }}</td>
+ <td>{{ chroot.state }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% endif %}
+ {% else %}
+ <h2>No builds so far.</h2>
+ {% endif %}
+{% endblock %}
diff --git a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
index 5874543..1d3750f 100644
--- a/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
+++ b/coprs_frontend/coprs/views/coprs_ns/coprs_general.py
@@ -344,3 +344,20 @@ def generate_repo_file(username, coprname, chroot):
response.mimetype='text/plain'
response.headers['Content-Disposition'] = 'filename=%s.repo' % reponame
return response
+
+(a)coprs_ns.route('/<username>/<coprname>/monitor/')
+def copr_build_monitor(username, coprname):
+ query = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname, with_mock_chroots=True)
+ form = forms.CoprLegalFlagForm()
+ try:
+ copr = query.one()
+ except sqlalchemy.orm.exc.NoResultFound:
+ return page_not_found('Copr with name {0} does not exist.'.format(coprname))
+
+ builds_query = builds_logic.BuildsLogic.get_multiple(flask.g.user, copr=copr)
+ build = builds_query.first()
+
+ return flask.render_template('coprs/detail/monitor.html',
+ copr=copr,
+ build=build,
+ form=form)
10 years, 5 months
[copr] enter_the_matrix: [tests]: replace test_allowed_one (c512d35)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit c512d357d41fc47191d417ea2c5b12e179061b58
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Thu Nov 14 16:10:07 2013 +0100
[tests]: replace test_allowed_one
Replaces failing test_allowed_one which doesn't make much sense
with test_allowed_one_but_... which checks the same thing.
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
copr.spec | 5 +----
.../test_views/test_coprs_ns/test_coprs_general.py | 8 +-------
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/copr.spec b/copr.spec
index 5203312..3c7afc5 100644
--- a/copr.spec
+++ b/copr.spec
@@ -263,10 +263,7 @@ install -p -m 644 man/%{name}-selinux-relabel.8 %{buildroot}/%{_mandir}/man8/
%check
%if ! 0%{?with_test:1}
pushd coprs_frontend
- TMPFILE=$(mktemp)
- COPR_CONFIG="$(pwd)/config/copr_unit_test.conf" ./manage.py test | tee $TMPFILE
- # remove this when tests are fixed
- grep "1 failed, 65 passed" $TMPFILE
+ COPR_CONFIG="$(pwd)/config/copr_unit_test.conf" ./manage.py test
popd
%endif
diff --git a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
index 179dad7..a05c54d 100644
--- a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
+++ b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
@@ -35,14 +35,8 @@ class TestCoprsAllowed(CoprsTestCase):
r = self.test_client.get('/coprs/{0}/allowed/'.format(self.u3.name))
assert 'No projects...' in r.data
- @TransactionDecorator('u2')
- def test_allowed_one(self, f_users, f_coprs, f_copr_permissions, f_db):
- self.db.session.add(self.u1)
- r = self.test_client.get('/coprs/{0}/allowed/'.format(self.u2.name))
- assert r.data.count('<div class="copr">') == 1
-
@TransactionDecorator('u1')
- def test_allowed_one_but_asked_for_one_more(self, f_users, f_coprs, f_copr_permissions, f_db):
+ def test_allowed_one(self, f_users, f_coprs, f_copr_permissions, f_db):
self.db.session.add(self.u1)
r = self.test_client.get('/coprs/{0}/allowed/'.format(self.u1.name))
assert r.data.count('<div class="copr">') == 1
10 years, 5 months
[copr] enter_the_matrix: [tests]: fix for BuildChroots & new backend view (0946ff2)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit 0946ff28f74abc98e6df87113fb5c852aea9f3b7
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Thu Nov 14 15:30:27 2013 +0100
[tests]: fix for BuildChroots & new backend view
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
.../test_backend_ns/test_backend_general.py | 54 ++++++++++++-------
.../test_views/test_coprs_ns/test_coprs_builds.py | 12 ++---
.../test_views/test_coprs_ns/test_coprs_general.py | 35 ++++++++++---
3 files changed, 66 insertions(+), 35 deletions(-)
diff --git a/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py b/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py
index 235ed98..322f01d 100644
--- a/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py
+++ b/coprs_frontend/tests/test_views/test_backend_ns/test_backend_general.py
@@ -1,20 +1,22 @@
import json
-import flask
-
from coprs.signals import build_finished
from tests.coprs_test_case import CoprsTestCase
+
class TestWaitingBuilds(CoprsTestCase):
def test_no_waiting_builds(self):
- assert '"builds": []' in self.tc.get('/backend/waiting_builds/').data
+ assert '"builds": []' in self.tc.get('/backend/waiting/', headers=self.auth_header).data
+
+ def test_waiting_build_only_lists_not_started_or_ended(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+
+ r = self.tc.get('/backend/waiting/', headers=self.auth_header)
+ assert len(json.loads(r.data)['builds']) == 4
- def test_waiting_build_only_lists_not_started_or_ended(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.get('/backend/waiting_builds/')
- assert len(json.loads(r.data)['builds']) == 2
class TestUpdateBuilds(CoprsTestCase):
- data1="""
+ data1= """
{
"builds":[
{
@@ -33,6 +35,7 @@ class TestUpdateBuilds(CoprsTestCase):
"id": 1,
"copr_id": 2,
"status": 1,
+ "chroot": "fedora-18-x86_64",
"ended_on": 12345
}
]
@@ -44,13 +47,14 @@ class TestUpdateBuilds(CoprsTestCase):
{
"id": 1,
"copr_id": 2,
- "results": "http://server/results/foo/bar/",
"started_on": 1234
},
{
"id": 2,
"copr_id": 1,
"status": 0,
+ "chroot": "fedora-18-x86_64",
+ "results": "http://server/results/foo/bar/",
"ended_on": 123456
},
{
@@ -68,13 +72,17 @@ class TestUpdateBuilds(CoprsTestCase):
]
}"""
def test_updating_requires_password(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.post('/backend/update_builds/',
+ r = self.tc.post('/backend/update/',
content_type = 'application/json',
data = '')
assert 'You have to provide the correct password' in r.data
def test_update_build_started(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.post('/backend/update_builds/',
+ self.b1.started_on = None
+ self.db.session.add(self.b1)
+ self.db.session.commit()
+
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data1)
@@ -85,8 +93,8 @@ class TestUpdateBuilds(CoprsTestCase):
assert updated.results == 'http://server/results/foo/bar/'
assert updated.started_on == 1234
- def test_update_build_ended(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.post('/backend/update_builds/',
+ def test_update_build_ended(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data2)
@@ -97,8 +105,14 @@ class TestUpdateBuilds(CoprsTestCase):
assert updated.status == 1
assert updated.ended_on == 12345
- def test_update_more_existent_and_non_existent_builds(self, f_users, f_coprs, f_builds, f_db):
- r = self.tc.post('/backend/update_builds/',
+ def test_update_more_existent_and_non_existent_builds(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+
+ self.b1.started_on = None
+ self.db.session.add(self.b1)
+ self.db.session.commit()
+
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data3)
@@ -107,11 +121,11 @@ class TestUpdateBuilds(CoprsTestCase):
assert sorted(json.loads(r.data)["non_existing_builds_ids"]) == [123321, 1234321]
started = self.models.Build.query.filter(self.models.Build.id==1).first()
- assert started.results == 'http://server/results/foo/bar/'
assert started.started_on == 1234
ended = self.models.Build.query.filter(self.models.Build.id==2).first()
assert ended.status == 0
+ assert ended.results == 'http://server/results/foo/bar/'
assert ended.ended_on == 123456
def test_build_ended_emmits_signal(self, f_users, f_coprs, f_builds, f_db):
@@ -120,7 +134,7 @@ class TestUpdateBuilds(CoprsTestCase):
def test_receiver(sender, **kwargs):
signals_received.append(kwargs['build'])
build_finished.connect(test_receiver)
- r = self.tc.post('/backend/update_builds/',
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data3)
@@ -130,10 +144,10 @@ class TestUpdateBuilds(CoprsTestCase):
class TestWaitingActions(CoprsTestCase):
def test_no_waiting_builds(self):
- assert '"actions": []' in self.tc.get('/backend/waiting_actions/').data
+ assert '"actions": []' in self.tc.get('/backend/waiting/', headers=self.auth_header).data
def test_waiting_build_only_lists_not_started_or_ended(self, f_users, f_coprs, f_actions, f_db):
- r = self.tc.get('/backend/waiting_actions/')
+ r = self.tc.get('/backend/waiting/', headers=self.auth_header)
assert len(json.loads(r.data)['actions']) == 2
class TestUpdateActions(CoprsTestCase):
@@ -173,7 +187,7 @@ class TestUpdateActions(CoprsTestCase):
}"""
def test_update_one_action(self, f_users, f_coprs, f_actions, f_db):
- r = self.tc.post('/backend/update_actions/',
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data1)
@@ -186,7 +200,7 @@ class TestUpdateActions(CoprsTestCase):
assert updated.ended_on == 123
def test_update_more_existent_and_non_existent_builds(self, f_users, f_coprs, f_actions, f_db):
- r = self.tc.post('/backend/update_actions/',
+ r = self.tc.post('/backend/update/',
content_type='application/json',
headers=self.auth_header,
data=self.data2)
diff --git a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
index 60bafb7..dc66562 100644
--- a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
+++ b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
@@ -1,15 +1,13 @@
-import flask
-
from tests.coprs_test_case import CoprsTestCase, TransactionDecorator
class TestCoprShowBuilds(CoprsTestCase):
- def test_copr_show_builds(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_show_builds(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
r = self.tc.get('/coprs/{0}/{1}/builds/'.format(self.u2.name, self.c2.name))
assert r.data.count('<tr class="build-') == 2
class TestCoprAddBuild(CoprsTestCase):
@TransactionDecorator('u1')
- def test_copr_owner_can_add_build(self, f_users, f_coprs, f_db):
+ def test_copr_owner_can_add_build(self, f_users, f_coprs, f_mock_chroots, f_db):
self.db.session.add_all([self.u1, self.c1])
r = self.test_client.post('/coprs/{0}/{1}/new_build/'.format(self.u1.name, self.c1.name),
data = {'pkgs': 'http://testing'},
@@ -17,7 +15,7 @@ class TestCoprAddBuild(CoprsTestCase):
assert self.models.Build.query.first().pkgs == 'http://testing'
@TransactionDecorator('u1')
- def test_copr_allowed_user_can_add_build(self, f_users, f_coprs, f_copr_permissions, f_db):
+ def test_copr_allowed_user_can_add_build(self, f_users, f_coprs, f_mock_chroots, f_copr_permissions, f_db):
self.db.session.add_all([self.u2, self.c2])
r = self.test_client.post('/coprs/{0}/{1}/new_build/'.format(self.u2.name, self.c2.name),
data = {'pkgs': 'http://testing'},
@@ -44,7 +42,7 @@ class TestCoprAddBuild(CoprsTestCase):
class TestCoprCancelBuild(CoprsTestCase):
@TransactionDecorator('u1')
- def test_copr_build_submitter_can_cancel_build(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_build_submitter_can_cancel_build(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
self.db.session.add_all([self.u1, self.c1, self.b1])
r = self.test_client.post('/coprs/{0}/{1}/cancel_build/{2}/'.format(self.u1.name, self.c1.name, self.b1.id),
data = {},
@@ -53,7 +51,7 @@ class TestCoprCancelBuild(CoprsTestCase):
@TransactionDecorator('u2')
- def test_copr_build_non_submitter_cannot_cancel_build(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_build_non_submitter_cannot_cancel_build(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
self.db.session.add_all([self.u1, self.c1, self.b1])
r = self.test_client.post('/coprs/{0}/{1}/cancel_build/{2}/'.format(self.u1.name, self.c1.name, self.b1.id),
data = {},
diff --git a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
index e02a0b3..179dad7 100644
--- a/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
+++ b/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_general.py
@@ -1,4 +1,3 @@
-import flask
import pytest
from flexmock import flexmock
@@ -132,7 +131,7 @@ class TestCoprDetail(CoprsTestCase):
assert r.status_code == 200
assert self.c1.name in r.data
- def test_copr_detail_contains_builds(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_detail_contains_builds(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
r = self.tc.get('/coprs/{0}/{1}/builds/'.format(self.u1.name, self.c1.name))
assert r.data.count('<tr class="build') == 2
@@ -173,13 +172,13 @@ class TestCoprDetail(CoprsTestCase):
assert '/cancel_build/' not in r.data
@TransactionDecorator('u1')
- def test_copr_detail_doesnt_allow_non_submitter_to_cancel_build(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_detail_doesnt_allow_non_submitter_to_cancel_build(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
self.db.session.add_all([self.u2, self.c2])
r = self.test_client.get('/coprs/{0}/{1}/builds/'.format(self.u2.name, self.c2.name))
assert '/cancel_build/' not in r.data
@TransactionDecorator('u2')
- def test_copr_detail_allows_submitter_to_cancel_build(self, f_users, f_coprs, f_builds, f_db):
+ def test_copr_detail_allows_submitter_to_cancel_build(self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
self.db.session.add_all([self.u2, self.c2])
r = self.test_client.get('/coprs/{0}/{1}/builds/'.format(self.u2.name, self.c2.name))
assert '/cancel_build/' in r.data
@@ -393,19 +392,39 @@ class TestCoprRepoGeneration(CoprsTestCase):
@pytest.fixture
def f_custom_builds(self):
''' Custom builds are used in order not to break the default ones '''
- self.b5 = self.models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=9, ended_on=200, results='http://bar.baz', status=1)
- self.b6 = self.models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=11)
- self.b7 = self.models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=10, ended_on=150, results='http://bar.baz', status=1)
+ self.b5 = self.models.Build(copr=self.c1, user=self.u1, submitted_on=9, ended_on=200, results='http://bar.baz')
+ self.b6 = self.models.Build(copr=self.c1, user=self.u1, submitted_on=11)
+ self.b7 = self.models.Build(copr=self.c1, user=self.u1, submitted_on=10, ended_on=150, results='http://bar.baz')
self.mc1 = self.models.MockChroot(os_release='fedora', os_version='18', arch='x86_64')
self.cc1 = self.models.CoprChroot(mock_chroot = self.mc1, copr = self.c1)
+
+
+ # assign with chroots
+ for build in [self.b5, self.b6, self.b7]:
+ self.db.session.add(
+ self.models.BuildChroot(
+ build=build,
+ mock_chroot=self.mc1
+ )
+ )
+
self.db.session.add_all([self.b5, self.b6, self.b7, self.mc1, self.cc1])
@pytest.fixture
def f_not_finished_builds(self):
''' Custom builds are used in order not to break the default ones '''
- self.b8 = self.models.Build(copr=self.c1, user=self.u1, chroots='fedora-18-x86_64', submitted_on=11)
+ self.b8 = self.models.Build(copr=self.c1, user=self.u1, submitted_on=11)
self.mc1 = self.models.MockChroot(os_release='fedora', os_version='18', arch='x86_64')
self.cc1 = self.models.CoprChroot(mock_chroot = self.mc1, copr = self.c1)
+
+ # assign with chroot
+ self.db.session.add(
+ self.models.BuildChroot(
+ build=self.b8,
+ mock_chroot=self.mc1
+ )
+ )
+
self.db.session.add_all([self.b8, self.mc1, self.cc1])
def test_fail_on_missing_dash(self):
10 years, 5 months
[copr] enter_the_matrix: [tests]: pep8 fixes (d77a4e1)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit d77a4e11c0937a5e711b91ba5dc62b0e812b81e2
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Thu Nov 14 16:02:35 2013 +0100
[tests]: pep8 fixes
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/tests/coprs_test_case.py | 94 ++++++++++++++++++++++---------
1 files changed, 67 insertions(+), 27 deletions(-)
diff --git a/coprs_frontend/tests/coprs_test_case.py b/coprs_frontend/tests/coprs_test_case.py
index 4685b25..8ff9c60 100644
--- a/coprs_frontend/tests/coprs_test_case.py
+++ b/coprs_frontend/tests/coprs_test_case.py
@@ -10,9 +10,10 @@ import coprs
from coprs import helpers
from coprs import models
-from coprs.logic.builds_logic import BuildsLogic
+
class CoprsTestCase(object):
+
def setup_method(self, method):
self.tc = coprs.app.test_client()
self.app = coprs.app
@@ -23,7 +24,8 @@ class CoprsTestCase(object):
self.helpers = helpers
self.backend_passwd = coprs.app.config['BACKEND_PASSWORD']
# create datadir if it doesn't exist
- datadir = os.path.commonprefix([self.app.config['DATABASE'], self.app.config['OPENID_STORE']])
+ datadir = os.path.commonprefix(
+ [self.app.config['DATABASE'], self.app.config['OPENID_STORE']])
if not os.path.exists(datadir):
os.makedirs(datadir)
coprs.db.create_all()
@@ -36,7 +38,8 @@ class CoprsTestCase(object):
@property
def auth_header(self):
- return {'Authorization': 'Basic ' + base64.b64encode('doesntmatter:{0}'.format(self.backend_passwd))}
+ return {'Authorization': 'Basic ' +
+ base64.b64encode('doesntmatter:{0}'.format(self.backend_passwd))}
@pytest.fixture
def f_db(self):
@@ -44,26 +47,42 @@ class CoprsTestCase(object):
@pytest.fixture
def f_users(self):
- self.u1 = models.User(openid_name=u'http://user1.id.fedoraproject.org/', proven=False, admin=True, mail='user1(a)foo.bar')
- self.u2 = models.User(openid_name=u'http://user2.id.fedoraproject.org/', proven = False, mail='user2(a)spam.foo')
- self.u3 = models.User(openid_name=u'http://user3.id.fedoraproject.org/', proven=False, mail='baz(a)bar.bar')
+ self.u1 = models.User(
+ openid_name=u'http://user1.id.fedoraproject.org/',
+ proven=False,
+ admin=True,
+ mail='user1(a)foo.bar')
+
+ self.u2 = models.User(
+ openid_name=u'http://user2.id.fedoraproject.org/',
+ proven=False,
+ mail='user2(a)spam.foo')
+
+ self.u3 = models.User(
+ openid_name=u'http://user3.id.fedoraproject.org/',
+ proven=False,
+ mail='baz(a)bar.bar')
self.db.session.add_all([self.u1, self.u2, self.u3])
@pytest.fixture
def f_coprs(self):
- self.c1 = models.Copr(name = u'foocopr', owner = self.u1)
- self.c2 = models.Copr(name = u'foocopr', owner = self.u2)
- self.c3 = models.Copr(name = u'barcopr', owner = self.u2)
+ self.c1 = models.Copr(name=u'foocopr', owner=self.u1)
+ self.c2 = models.Copr(name=u'foocopr', owner=self.u2)
+ self.c3 = models.Copr(name=u'barcopr', owner=self.u2)
self.db.session.add_all([self.c1, self.c2, self.c3])
@pytest.fixture
def f_mock_chroots(self):
- self.mc1 = models.MockChroot(os_release='fedora', os_version='18', arch='x86_64', is_active=True)
- self.mc2 = models.MockChroot(os_release='fedora', os_version='17', arch='x86_64', is_active=True)
- self.mc3 = models.MockChroot(os_release='fedora', os_version='17', arch='i386', is_active=True)
- self.mc4 = models.MockChroot(os_release='fedora', os_version='rawhide', arch='i386', is_active=True)
+ self.mc1 = models.MockChroot(
+ os_release='fedora', os_version='18', arch='x86_64', is_active=True)
+ self.mc2 = models.MockChroot(
+ os_release='fedora', os_version='17', arch='x86_64', is_active=True)
+ self.mc3 = models.MockChroot(
+ os_release='fedora', os_version='17', arch='i386', is_active=True)
+ self.mc4 = models.MockChroot(
+ os_release='fedora', os_version='rawhide', arch='i386', is_active=True)
# only bind to coprs if the test has used the f_coprs fixture
if hasattr(self, 'c1'):
@@ -90,10 +109,14 @@ class CoprsTestCase(object):
@pytest.fixture
def f_builds(self):
- self.b1 = models.Build(copr = self.c1, user = self.u1, submitted_on = 50, started_on = 100)
- self.b2 = models.Build(copr = self.c1, user = self.u2, submitted_on = 10, ended_on = 150)
- self.b3 = models.Build(copr = self.c2, user = self.u2, submitted_on = 10)
- self.b4 = models.Build(copr = self.c2, user = self.u2, submitted_on = 100)
+ self.b1 = models.Build(
+ copr=self.c1, user=self.u1, submitted_on=50, started_on=100)
+ self.b2 = models.Build(
+ copr=self.c1, user=self.u2, submitted_on=10, ended_on=150)
+ self.b3 = models.Build(
+ copr=self.c2, user=self.u2, submitted_on=10)
+ self.b4 = models.Build(
+ copr=self.c2, user=self.u2, submitted_on=100)
for build in [self.b1, self.b2, self.b3, self.b4]:
self.db.session.add(build)
@@ -109,27 +132,46 @@ class CoprsTestCase(object):
@pytest.fixture
def f_copr_permissions(self):
- self.cp1 = models.CoprPermission(copr = self.c2, user = self.u1, copr_builder = helpers.PermissionEnum('approved'), copr_admin = helpers.PermissionEnum('nothing'))
- self.cp2 = models.CoprPermission(copr = self.c3, user = self.u3, copr_builder = helpers.PermissionEnum('nothing'), copr_admin = helpers.PermissionEnum('nothing'))
- self.cp3 = models.CoprPermission(copr = self.c3, user = self.u1, copr_builder = helpers.PermissionEnum('request'), copr_admin = helpers.PermissionEnum('approved'))
+ self.cp1 = models.CoprPermission(
+ copr=self.c2,
+ user=self.u1,
+ copr_builder=helpers.PermissionEnum('approved'),
+ copr_admin=helpers.PermissionEnum('nothing'))
+
+ self.cp2 = models.CoprPermission(
+ copr=self.c3,
+ user=self.u3,
+ copr_builder=helpers.PermissionEnum('nothing'),
+ copr_admin=helpers.PermissionEnum('nothing'))
+
+ self.cp3 = models.CoprPermission(
+ copr=self.c3,
+ user=self.u1,
+ copr_builder=helpers.PermissionEnum('request'),
+ copr_admin=helpers.PermissionEnum('approved'))
self.db.session.add_all([self.cp1, self.cp2, self.cp3])
@pytest.fixture
def f_actions(self):
- # if using actions, we need to flush coprs into db, so that we can get their ids
+ # if using actions, we need to flush coprs into db, so that we can get
+ # their ids
self.f_db()
self.a1 = models.Action(action_type=helpers.ActionTypeEnum('rename'),
object_type='copr',
object_id=self.c1.id,
- old_value='{0}/{1}'.format(self.c1.owner.name, self.c1.name),
- new_value='{0}/new_name'.format(self.c1.owner.name),
+ old_value='{0}/{1}'.format(
+ self.c1.owner.name, self.c1.name),
+ new_value='{0}/new_name'.format(
+ self.c1.owner.name),
created_on=int(time.time()))
self.a2 = models.Action(action_type=helpers.ActionTypeEnum('rename'),
object_type='copr',
object_id=self.c2.id,
- old_value='{0}/{1}'.format(self.c2.owner.name, self.c2.name),
- new_value='{0}/new_name2'.format(self.c2.owner.name),
+ old_value='{0}/{1}'.format(
+ self.c2.owner.name, self.c2.name),
+ new_value='{0}/new_name2'.format(
+ self.c2.owner.name),
created_on=int(time.time()))
self.a3 = models.Action(action_type=helpers.ActionTypeEnum('delete'),
object_type='copr',
@@ -141,8 +183,6 @@ class CoprsTestCase(object):
self.db.session.add_all([self.a1, self.a2, self.a3])
-
-
class TransactionDecorator(object):
"""
10 years, 5 months
[copr] enter_the_matrix: [frontend] create BuildChroot objects on new build (9281772)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit 92817726943ab44438eb6b764ec2e8e6e8b2cbde
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Tue Nov 12 17:33:17 2013 +0100
[frontend] create BuildChroot objects on new build
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/logic/builds_logic.py | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/logic/builds_logic.py b/coprs_frontend/coprs/logic/builds_logic.py
index bbcd639..406f94e 100644
--- a/coprs_frontend/coprs/logic/builds_logic.py
+++ b/coprs_frontend/coprs/logic/builds_logic.py
@@ -66,7 +66,6 @@ class BuildsLogic(object):
pkgs=pkgs,
copr=copr,
repos=copr.repos,
- chroots=' '.join(map(lambda x: x.chroot_name, copr.active_mock_chroots)),
user=user,
submitted_on=int(time.time()))
cls.new(user, build, copr)
@@ -82,6 +81,15 @@ class BuildsLogic(object):
coprs_logic.CoprsLogic.increment_build_count(user, copr)
db.session.add(build)
+ # add BuildChroot object for each active chroot
+ # this copr is assigned to
+ for chroot in copr.active_mock_chroots:
+ buildchroot = models.BuildChroot(
+ build=build,
+ mock_chroot=chroot)
+
+ db.session.add(buildchroot)
+
@classmethod
def update_state_from_dict(cls, user, build, upd_dict):
for attr in ['results', 'started_on', 'ended_on', 'status']:
10 years, 5 months
[copr] enter_the_matrix: [frontend] add ActionsLogic (98e96ac)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit 98e96ac003d2912c48c710072f85fe51c23e7c47
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Wed Nov 13 16:07:53 2013 +0100
[frontend] add ActionsLogic
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/logic/actions_logic.py | 40 +++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/coprs_frontend/coprs/logic/actions_logic.py b/coprs_frontend/coprs/logic/actions_logic.py
new file mode 100644
index 0000000..d53ef8b
--- /dev/null
+++ b/coprs_frontend/coprs/logic/actions_logic.py
@@ -0,0 +1,40 @@
+from coprs import db
+from coprs import models
+from coprs import helpers
+
+
+class ActionsLogic(object):
+ @classmethod
+ def get(cls, action_id):
+ """ Return single action identified by `action_id` """
+ query = models.Action.query.filter(models.Action.id == action_id)
+ return query
+
+ @classmethod
+ def get_waiting(cls):
+ """ Return actions that aren't finished """
+ query = (models.Action.query
+ .filter(models.Action.result ==
+ helpers.BackendResultEnum('waiting'))
+ .order_by(models.Action.created_on.asc()))
+
+ return query
+
+ @classmethod
+ def get_by_ids(cls, ids):
+ """ Return actions matching passed `ids` """
+ return models.Action.query.filter(models.Action.id.in_(ids))
+
+ @classmethod
+ def update_state_from_dict(cls, action, upd_dict):
+ """
+ Update `action` object with `upd_dict` data
+
+ Updates result, message and ended_on parameters.
+ """
+ for attr in ['result', 'message', 'ended_on']:
+ value = upd_dict.get(attr, None)
+ if value:
+ setattr(action, attr, value)
+
+ db.session.add(action)
10 years, 5 months
[copr] enter_the_matrix: [frontend] add Build <-> Chroot relation (fa2693b)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit fa2693b70341cda6ee3f538390c08df0f6da07a0
Author: Richard Marko <rmarko(a)fedoraproject.org>
Date: Tue Nov 12 17:32:36 2013 +0100
[frontend] add Build <-> Chroot relation
Signed-off-by: Richard Marko <rmarko(a)fedoraproject.org>
>---------------------------------------------------------------
coprs_frontend/coprs/models.py | 58 +++++++++++++++++++++++++++-------------
1 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index 41c0b3f..48cf8a0 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -199,10 +199,6 @@ class Build(db.Model, Serializer):
pkgs = db.Column(db.Text)
# was this build canceled by user?
canceled = db.Column(db.Boolean, default = False)
- ## These two are present for every build, as they might change in Copr
- ## between submitting and starting build => we want to keep them as submitted
- # list of space separated mock chroot names
- chroots = db.Column(db.Text, nullable = False)
# list of space separated additional repos
repos = db.Column(db.Text)
## the three below represent time of important events for this build
@@ -212,9 +208,6 @@ class Build(db.Model, Serializer):
ended_on = db.Column(db.Integer)
# url of the build results
results = db.Column(db.Text)
- # status as returned by backend, see build.state for value explanation
- # (TODO: this would deserve an enum)
- status = db.Column(db.Integer)
# memory requirements for backend builder
memory_reqs = db.Column(db.Integer, default = constants.DEFAULT_BUILD_MEMORY)
# maximum allowed time of build, build will fail if exceeded
@@ -226,26 +219,41 @@ class Build(db.Model, Serializer):
copr_id = db.Column(db.Integer, db.ForeignKey('copr.id'))
copr = db.relationship('Copr', backref = db.backref('builds'))
+ chroots = association_proxy('build_chroots', 'mock_chroot')
+
@property
- def state(self):
- """Return text representation of status of this build"""
- if self.status == 1:
- return 'succeeded'
- elif self.status == 0:
- return 'failed'
+ def chroot_states(self):
+ return map(lambda chroot: chroot.status, self.build_chroots)
+
+ @property
+ def has_pending_chroot(self):
+ return helpers.StatusEnum('pending') in self.chroot_states
+
+ @property
+ def status(self):
+ """ Return build status according to build status of its chroots """
if self.canceled:
- return 'canceled'
- if not self.ended_on and self.started_on:
- return 'running'
- return 'pending'
+ return helpers.StatusEnum('canceled')
+
+ for state in ['failed', 'running', 'pending', 'succeeded']:
+ if helpers.StatusEnum(state) in self.chroot_states:
+ return helpers.StatusEnum(state)
+
+ @property
+ def state(self):
+ """ Return text representation of status of this build """
+ return helpers.StatusEnum(self.status)
@property
def cancelable(self):
- """Find out if this build is cancelable.
+ """
+ Find out if this build is cancelable.
ATM, build is cancelable only if it wasn't grabbed by backend.
"""
- return self.state == 'pending'
+
+ return self.status == helpers.StatusEnum('pending')
+
class MockChroot(db.Model, Serializer):
"""Representation of mock chroot"""
@@ -278,6 +286,18 @@ class CoprChroot(db.Model, Serializer):
single_parent=True,
cascade='all,delete,delete-orphan'))
+
+class BuildChroot(db.Model, Serializer):
+ """Representation of Build<->MockChroot relation"""
+ mock_chroot_id = db.Column(db.Integer, db.ForeignKey('mock_chroot.id'),
+ primary_key=True)
+ mock_chroot = db.relationship('MockChroot', backref=db.backref('builds'))
+ build_id = db.Column(db.Integer, db.ForeignKey('build.id'),
+ primary_key=True)
+ build = db.relationship('Build', backref=db.backref('build_chroots'))
+ status = db.Column(db.Integer, default=helpers.StatusEnum('pending'))
+
+
class LegalFlag(db.Model, Serializer):
id = db.Column(db.Integer, primary_key=True)
# message from user who raised the flag (what he thinks is wrong)
10 years, 5 months
[copr] enter_the_matrix: add migration script - add table build_chroot (f771778)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit f771778334459de37009fa066f164855a127a13e
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Thu Nov 14 14:49:11 2013 +0100
add migration script - add table build_chroot
>---------------------------------------------------------------
.../versions/52e53e7b413e_add_build_chroot.py | 70 ++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/coprs_frontend/alembic/versions/52e53e7b413e_add_build_chroot.py b/coprs_frontend/alembic/versions/52e53e7b413e_add_build_chroot.py
new file mode 100644
index 0000000..afb0cfb
--- /dev/null
+++ b/coprs_frontend/alembic/versions/52e53e7b413e_add_build_chroot.py
@@ -0,0 +1,70 @@
+""" Add BuildChroot table
+
+Revision ID: 52e53e7b413e
+Revises: 246fd2dbf398
+Create Date: 2013-11-14 09:00:43.787717
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '52e53e7b413e'
+down_revision = '246fd2dbf398'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ ### commands auto generated by Alembic - please adjust! ###
+ op.create_table('build_chroot',
+ sa.Column('mock_chroot_id', sa.Integer(), nullable=False),
+ sa.Column('build_id', sa.Integer(), nullable=False),
+ sa.Column('status', sa.Integer(), nullable=True),
+ sa.ForeignKeyConstraint(['build_id'], ['build.id'], ),
+ sa.ForeignKeyConstraint(['mock_chroot_id'], ['mock_chroot.id'], ),
+ sa.PrimaryKeyConstraint('mock_chroot_id', 'build_id')
+ )
+
+ #transfer data from build table to build_chroot
+ session = sa.orm.sessionmaker(bind=op.get_bind())()
+ metadata = sa.MetaData()
+ # just what we need of copr table
+ build_table = sa.Table('build', metadata,
+ sa.Column('chroots', sa.Text()),
+ sa.Column('status', sa.Integer()),
+ sa.Column('id', sa.Integer()),
+ )
+
+ mc_table = sa.Table('mock_chroot', metadata,
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('os_release', sa.String(length=50), nullable=False),
+ sa.Column('os_version', sa.String(length=50), nullable=False),
+ sa.Column('arch', sa.String(length=50), nullable=False),
+ sa.Column('is_active', sa.Boolean(), nullable=False),
+ )
+ bc_table = sa.Table('build_chroot', metadata,
+ sa.Column('mock_chroot_id', sa.Integer(), nullable=False),
+ sa.Column('build_id', sa.Integer(), nullable=False),
+ sa.Column('status', sa.Integer(), nullable=True),
+ )
+ for row in op.get_bind().execute(sa.select([build_table.c.id, build_table.c.chroots, build_table.c.status])):
+ for c in row[1].split(' '):
+ chroot_array = c.split('-')
+ for row2 in (op.get_bind().execute(sa.select([mc_table.c.id], sa.and_(
+ mc_table.c.os_release == op.inline_literal(chroot_array[0]),
+ mc_table.c.os_version == op.inline_literal(chroot_array[1]),
+ mc_table.c.arch == op.inline_literal(chroot_array[2]),
+ )))): # should be just one row
+ op.bulk_insert(bc_table, [{'mock_chroot_id': row2[0], 'build_id': row[0], 'status': row[2]}])
+
+ # drop old columns
+ op.drop_column(u'build', u'status')
+ op.drop_column(u'build', u'chroots')
+
+
+def downgrade():
+ print "Why are you downgrading? You will just lost some data."
+ op.add_column(u'build', sa.Column(u'chroots', sa.TEXT(), nullable=False))
+ op.add_column(u'build', sa.Column(u'status', sa.INTEGER(), nullable=True))
+ op.drop_table('build_chroot')
+ print "Data about chroots for builds are gone!"
10 years, 5 months
[copr] enter_the_matrix: [spec] enable/disable test using variable (14464fd)
by Richard Marko
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : enter_the_matrix
>---------------------------------------------------------------
commit 14464fde5b1c6e45bd8aabb4db2254f09bedb2df
Author: Miroslav Suchý <msuchy(a)redhat.com>
Date: Thu Nov 14 15:06:09 2013 +0100
[spec] enable/disable test using variable
>---------------------------------------------------------------
copr.spec | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/copr.spec b/copr.spec
index 4becc12..5203312 100644
--- a/copr.spec
+++ b/copr.spec
@@ -1,3 +1,4 @@
+%global with_test 0
%if 0%{?rhel} < 7 && 0%{?rhel} > 0
%global _pkgdocdir %{_docdir}/%{name}-%{version}
%endif
@@ -260,12 +261,14 @@ install -p -m 644 man/%{name}-selinux-enable.8 %{buildroot}/%{_mandir}/man8/
install -p -m 644 man/%{name}-selinux-relabel.8 %{buildroot}/%{_mandir}/man8/
%check
-pushd coprs_frontend
-TMPFILE=$(mktemp)
-COPR_CONFIG="$(pwd)/config/copr_unit_test.conf" ./manage.py test | tee $TMPFILE
-# remove this when tests are fixed
-grep "1 failed, 65 passed" $TMPFILE
-popd
+%if ! 0%{?with_test:1}
+ pushd coprs_frontend
+ TMPFILE=$(mktemp)
+ COPR_CONFIG="$(pwd)/config/copr_unit_test.conf" ./manage.py test | tee $TMPFILE
+ # remove this when tests are fixed
+ grep "1 failed, 65 passed" $TMPFILE
+ popd
+%endif
%pre backend
getent group copr >/dev/null || groupadd -r copr
10 years, 5 months