Repository :
http://git.fedorahosted.org/cgit/copr.git
On branch : master
---------------------------------------------------------------
commit ea42e4f9b871e985db391ee288ac5c8bc98d8fc7
Author: Valentin Gologuzov <vgologuz(a)redhat.com>
Date: Fri Jan 30 14:53:07 2015 +0100
[frontend] [rhbz:#1171796] copr sometimes doesn't delete build from repository
---------------------------------------------------------------
.../coprs_frontend/coprs/logic/builds_logic.py | 41 +++++++-----
.../tests/test_logic/test_builds_logic.py | 73 +++++++++++++++++++-
.../test_views/test_coprs_ns/test_coprs_builds.py | 2 +-
3 files changed, 97 insertions(+), 19 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py
b/frontend/coprs_frontend/coprs/logic/builds_logic.py
index 5559722..d1cd9b8 100644
--- a/frontend/coprs_frontend/coprs/logic/builds_logic.py
+++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py
@@ -212,23 +212,30 @@ class BuildsLogic(object):
"You can not delete build which is not finished.",
"Unfinished build")
- # Only failed (and finished), succeeded, skipped and cancelled get here.
- if build.state != "cancelled": # has nothing in backend to delete
- object_type = "build-{0}".format(build.state)
- data_dict = {"pkgs": build.pkgs,
- "username": build.copr.owner.name,
- "projectname": build.copr.name}
-
- action = models.Action(
- action_type=helpers.ActionTypeEnum("delete"),
- object_type=object_type,
- object_id=build.id,
- old_value="{0}/{1}".format(build.copr.owner.name,
- build.copr.name),
- data=json.dumps(data_dict),
- created_on=int(time.time())
- )
- db.session.add(action)
+ # Only failed, finished, succeeded get here.
+ if build.state not in ["cancelled"]: # has nothing in backend to
delete
+ # don't delete skipped chroots
+ chroots_to_delete = [
+ chroot.name for chroot in build.build_chroots
+ if chroot.state not in ["skipped"]
+ ]
+
+ if chroots_to_delete:
+ data_dict = {"pkgs": build.pkgs,
+ "username": build.copr.owner.name,
+ "projectname": build.copr.name,
+ "chroots": chroots_to_delete}
+
+ action = models.Action(
+ action_type=helpers.ActionTypeEnum("delete"),
+ object_type="build",
+ object_id=build.id,
+ old_value="{0}/{1}".format(build.copr.owner.name,
+ build.copr.name),
+ data=json.dumps(data_dict),
+ created_on=int(time.time())
+ )
+ db.session.add(action)
for build_chroot in build.build_chroots:
db.session.delete(build_chroot)
diff --git a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
index c7dc07e..ef43cd0 100644
--- a/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
+++ b/frontend/coprs_frontend/tests/test_logic/test_builds_logic.py
@@ -1,10 +1,13 @@
# -*- encoding: utf-8 -*-
+import json
import pytest
import time
+from sqlalchemy.orm.exc import NoResultFound
from coprs import helpers
-from coprs.exceptions import ActionInProgressException
+from coprs.exceptions import ActionInProgressException, InsufficientRightsException
+from coprs.logic.actions_logic import ActionsLogic
from coprs.logic.builds_logic import BuildsLogic
from coprs.logic.builds_logic import BuildsMonitorLogic
@@ -88,3 +91,71 @@ class TestBuildsLogic(CoprsTestCase):
assert len(data) == 1
assert data[0] == self.b1_bc[0]
+
+ def test_delete_build_exceptions(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+ self.db.session.commit()
+ with pytest.raises(InsufficientRightsException):
+ BuildsLogic.delete_build(self.u1, self.b4)
+
+ self.b1_bc[0].status = "running"
+ self.db.session.add(self.b1_bc[0])
+ self.db.session.commit()
+ with pytest.raises(ActionInProgressException):
+ BuildsLogic.delete_build(self.u1, self.b1)
+
+ def test_delete_build_basic(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+ self.db.session.commit()
+
+ expected_chroots_to_delete = set()
+ for bchroot in self.b1_bc:
+ expected_chroots_to_delete.add(bchroot.name)
+
+ assert len(ActionsLogic.get_many().all()) == 0
+ BuildsLogic.delete_build(self.u1, self.b1)
+ self.db.session.commit()
+
+ assert len(ActionsLogic.get_many().all()) == 1
+ action = ActionsLogic.get_many().one()
+ delete_data = json.loads(action.data)
+ assert "chroots" in delete_data
+ assert expected_chroots_to_delete == set(delete_data["chroots"])
+
+ with pytest.raises(NoResultFound):
+ BuildsLogic.get(self.b1.id).one()
+
+ def test_delete_build_no_chroots_to_clean(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+
+ for bchroot in self.b1_bc:
+ bchroot.status = helpers.StatusEnum("skipped")
+
+ self.db.session.commit()
+ assert len(ActionsLogic.get_many().all()) == 0
+ BuildsLogic.delete_build(self.u1, self.b1)
+ self.db.session.commit()
+ assert len(ActionsLogic.get_many().all()) == 0
+
+ def test_delete_build_some_chroots(
+ self, f_users, f_coprs, f_mock_chroots, f_builds, f_db):
+
+ expected_chroots_to_delete = set([self.b1_bc[0].name,
+ self.b1_bc[-1].name])
+ for bchroot in self.b1_bc[1:-1]:
+ bchroot.status = helpers.StatusEnum("skipped")
+
+ self.db.session.commit()
+
+ assert len(ActionsLogic.get_many().all()) == 0
+ BuildsLogic.delete_build(self.u1, self.b1)
+ self.db.session.commit()
+
+ assert len(ActionsLogic.get_many().all()) == 1
+ action = ActionsLogic.get_many().one()
+ delete_data = json.loads(action.data)
+ assert "chroots" in delete_data
+ assert expected_chroots_to_delete == set(delete_data["chroots"])
+
+ with pytest.raises(NoResultFound):
+ BuildsLogic.get(self.b1.id).one()
diff --git a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
index 889f5e7..6a72158 100644
--- a/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
+++ b/frontend/coprs_frontend/tests/test_views/test_coprs_ns/test_coprs_builds.py
@@ -118,7 +118,7 @@ class TestCoprDeleteBuild(CoprsTestCase):
.first())
assert b is None
act = self.models.Action.query.first()
- assert act.object_type == "build-succeeded"
+ assert act.object_type == "build"
assert act.old_value == "user1/foocopr"
assert json.loads(act.data)["pkgs"] == pkgs