Separate use of database sessions

This patch separates the use of database session in different MBS components
and do not mix them together.

In general, MBS components could be separated as the REST API (implemented
based on Flask) and non-REST API including the backend build workflow
(implemented as a fedmsg consumer on top of fedmsg-hub and running
independently) and library shared by them. As a result, there are two kind of
database session used in MBS, one is created and managed by Flask-SQLAlchemy,
and another one is created from SQLAclhemy Session API directly. The goal of
this patch is to make ensure session object is used properly in the right
place.

All the changes follow these rules:

* REST API related code uses the session object db.session created and
  managed by Flask-SQLAlchemy.
* Non-REST API related code uses the session object created with SQLAlchemy
  Session API. Function make_db_session does that.
* Shared code does not created a new session object as much as possible.
  Instead, it accepts an argument db_session.

The first two rules are applicable to tests as well.

Major changes:

* Switch tests back to run with a file-based SQLite database.
* make_session is renamed to make_db_session and SQLAlchemy connection pool
  options are applied for PostgreSQL backend.
* Frontend Flask related code uses db.session
* Shared code by REST API and backend build workflow accepts SQLAlchemy session
  object as an argument. For example, resolver class is constructed with a
  database session, and some functions accepts an argument for database session.
* Build workflow related code use session object returned from make_db_session
  and ensure db.session is not used.
* Only tests for views use db.session, and other tests use db_session fixture
  to access database.
* All argument name session, that is for database access, are renamed to
  db_session.
* Functions model_tests_init_data, reuse_component_init_data and
  reuse_shared_userspace_init_data, which creates fixture data for
  tests, are converted into pytest fixtures from original function
  called inside setup_method or a test method. The reason of this
  conversion is to use fixture ``db_session`` rather than create a
  new one. That would also benefit the whole test suite to reduce the
  number of SQLAlchemy session objects.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
This commit is contained in:
Chenxiong Qi
2019-07-12 23:43:17 +08:00
parent 64698fbde8
commit 3878affa41
54 changed files with 2692 additions and 2454 deletions

View File

@@ -25,7 +25,7 @@ import pytest
from mock import call, patch, Mock
from sqlalchemy import func
from module_build_service import conf, db
from module_build_service import conf
from module_build_service.models import BUILD_STATES, ModuleBuild
from module_build_service.scheduler.consumer import MBSConsumer
from module_build_service.scheduler.handlers.greenwave import get_corresponding_module_build
@@ -40,10 +40,10 @@ class TestGetCorrespondingModuleBuild:
clean_database()
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_module_build_nvr_does_not_exist_in_koji(self, ClientSession):
def test_module_build_nvr_does_not_exist_in_koji(self, ClientSession, db_session):
ClientSession.return_value.getBuild.return_value = None
assert get_corresponding_module_build(db.session, "n-v-r") is None
assert get_corresponding_module_build(db_session, "n-v-r") is None
@pytest.mark.parametrize(
"build_info",
@@ -57,32 +57,34 @@ class TestGetCorrespondingModuleBuild:
],
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_cannot_find_module_build_id_from_build_info(self, ClientSession, build_info):
def test_cannot_find_module_build_id_from_build_info(
self, ClientSession, build_info, db_session
):
ClientSession.return_value.getBuild.return_value = build_info
assert get_corresponding_module_build(db.session, "n-v-r") is None
assert get_corresponding_module_build(db_session, "n-v-r") is None
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_corresponding_module_build_id_does_not_exist_in_db(self, ClientSession):
fake_module_build_id, = db.session.query(func.max(ModuleBuild.id)).first()
def test_corresponding_module_build_id_does_not_exist_in_db(self, ClientSession, db_session):
fake_module_build_id, = db_session.query(func.max(ModuleBuild.id)).first()
ClientSession.return_value.getBuild.return_value = {
"extra": {"typeinfo": {"module": {"module_build_service_id": fake_module_build_id + 1}}}
}
assert get_corresponding_module_build(db.session, "n-v-r") is None
assert get_corresponding_module_build(db_session, "n-v-r") is None
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_find_the_module_build(self, ClientSession):
def test_find_the_module_build(self, ClientSession, db_session):
expected_module_build = (
db.session.query(ModuleBuild).filter(ModuleBuild.name == "platform").first()
db_session.query(ModuleBuild).filter(ModuleBuild.name == "platform").first()
)
ClientSession.return_value.getBuild.return_value = {
"extra": {"typeinfo": {"module": {"module_build_service_id": expected_module_build.id}}}
}
build = get_corresponding_module_build(db.session, "n-v-r")
build = get_corresponding_module_build(db_session, "n-v-r")
assert expected_module_build.id == build.id
assert expected_module_build.name == build.name
@@ -92,9 +94,9 @@ class TestDecisionUpdateHandler:
"""Test handler decision_update"""
@patch("module_build_service.scheduler.handlers.greenwave.log")
def test_decision_context_is_not_match(self, log):
def test_decision_context_is_not_match(self, log, db_session):
msg = Mock(msg_id="msg-id-1", decision_context="bodhi_update_push_testing")
decision_update(conf, db.session, msg)
decision_update(conf, db_session, msg)
log.debug.assert_called_once_with(
'Skip Greenwave message %s as MBS only handles messages with the decision context "%s"',
"msg-id-1",
@@ -102,14 +104,14 @@ class TestDecisionUpdateHandler:
)
@patch("module_build_service.scheduler.handlers.greenwave.log")
def test_not_satisfy_policies(self, log):
def test_not_satisfy_policies(self, log, db_session):
msg = Mock(
msg_id="msg-id-1",
decision_context="test_dec_context",
policies_satisfied=False,
subject_identifier="pkg-0.1-1.c1",
)
decision_update(conf, db.session, msg)
decision_update(conf, db_session, msg)
log.debug.assert_called_once_with(
"Skip to handle module build %s because it has not satisfied Greenwave policies.",
msg.subject_identifier,
@@ -117,21 +119,21 @@ class TestDecisionUpdateHandler:
@patch("module_build_service.messaging.publish")
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_transform_from_done_to_ready(self, ClientSession, publish):
def test_transform_from_done_to_ready(self, ClientSession, publish, db_session):
clean_database()
# This build should be queried and transformed to ready state
module_build = make_module(db.session, "pkg:0.1:1:c1", requires_list={"platform": "el8"})
module_build = make_module(db_session, "pkg:0.1:1:c1", requires_list={"platform": "el8"})
module_build.transition(
conf, BUILD_STATES["done"], "Move to done directly for running test."
db_session, conf, BUILD_STATES["done"], "Move to done directly for running test."
)
db.session.commit()
db_session.commit()
# Assert this call below
first_publish_call = call(
service="mbs",
topic="module.state.change",
msg=module_build.json(show_tasks=False),
msg=module_build.json(db_session, show_tasks=False),
conf=conf,
)
@@ -153,9 +155,7 @@ class TestDecisionUpdateHandler:
consumer.consume(msg)
# Load module build again to check its state is moved correctly
module_build = (
db.session.query(ModuleBuild).filter(ModuleBuild.id == module_build.id).first())
db_session.refresh(module_build)
assert BUILD_STATES["ready"] == module_build.state
publish.assert_has_calls([
@@ -163,7 +163,7 @@ class TestDecisionUpdateHandler:
call(
service="mbs",
topic="module.state.change",
msg=module_build.json(show_tasks=False),
msg=module_build.json(db_session, show_tasks=False),
conf=conf,
),
])

View File

@@ -28,7 +28,7 @@ from tests.test_views.test_views import FakeSCM
import module_build_service.messaging
import module_build_service.scheduler.handlers.modules
from module_build_service import build_logs
from module_build_service.models import make_session, ModuleBuild, ComponentBuild
from module_build_service.models import make_db_session, ModuleBuild
from module_build_service.utils.general import mmd_to_str, load_mmd
@@ -41,13 +41,14 @@ class TestModuleInit:
mmd = mmd.copy("testmodule", "1")
scmurl = "git://pkgs.domain.local/modules/testmodule?#620ec77"
clean_database()
with make_session(conf) as session:
with make_db_session(conf) as session:
ModuleBuild.create(
session, conf, "testmodule", "1", 3, mmd_to_str(mmd), scmurl, "mprahl")
def teardown_method(self, test_method):
try:
path = build_logs.path(1)
with make_db_session(conf) as db_session:
path = build_logs.path(db_session, 1)
os.remove(path)
except Exception:
pass
@@ -90,7 +91,7 @@ class TestModuleInit:
msg_id=None, module_build_id=2, module_build_state="init"
)
self.fn(config=conf, session=db_session, msg=msg)
self.fn(config=conf, db_session=db_session, msg=msg)
build = ModuleBuild.get_by_id(db_session, 2)
# Make sure the module entered the wait state
@@ -122,18 +123,18 @@ class TestModuleInit:
@patch("module_build_service.scm.SCM")
@patch("module_build_service.utils.submit.get_build_arches", return_value=["x86_64"])
def test_init_scm_not_available(self, get_build_arches, mocked_scm):
def mocked_scm_get_latest():
raise RuntimeError("Failed in mocked_scm_get_latest")
def test_init_scm_not_available(self, get_build_arches, mocked_scm, db_session):
FakeSCM(
mocked_scm, "testmodule", "testmodule.yaml", "620ec77321b2ea7b0d67d82992dda3e1d67055b4")
mocked_scm.return_value.get_latest = mocked_scm_get_latest
mocked_scm, "testmodule", "testmodule.yaml", "620ec77321b2ea7b0d67d82992dda3e1d67055b4",
get_latest_raise=True,
get_latest_error=RuntimeError("Failed in mocked_scm_get_latest")
)
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="init")
with make_session(conf) as session:
self.fn(config=conf, session=session, msg=msg)
build = ModuleBuild.query.filter_by(id=2).one()
self.fn(config=conf, db_session=db_session, msg=msg)
build = ModuleBuild.get_by_id(db_session, 2)
# Make sure the module entered the failed state
# since the git server is not available
assert build.state == 4, build.state
@@ -145,24 +146,25 @@ class TestModuleInit:
)
@patch("module_build_service.scm.SCM")
@patch("module_build_service.utils.submit.get_build_arches", return_value=["x86_64"])
def test_init_includedmodule(self, get_build_arches, mocked_scm, mocked_mod_allow_repo):
def test_init_includedmodule(
self, get_build_arches, mocked_scm, mocked_mod_allow_repo, db_session
):
FakeSCM(mocked_scm, "includedmodules", ["testmodule_init.yaml"])
includedmodules_yml_path = read_staged_data("includedmodules")
mmd = load_mmd(includedmodules_yml_path)
# Set the name and stream
mmd = mmd.copy("includedmodules", "1")
scmurl = "git://pkgs.domain.local/modules/includedmodule?#da95886"
with make_session(conf) as session:
ModuleBuild.create(
session, conf, "includemodule", "1", 3, mmd_to_str(mmd), scmurl, "mprahl")
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=3, module_build_state="init")
self.fn(config=conf, session=session, msg=msg)
build = ModuleBuild.query.filter_by(id=3).one()
ModuleBuild.create(
db_session, conf, "includemodule", "1", 3, mmd_to_str(mmd), scmurl, "mprahl")
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=3, module_build_state="init")
self.fn(config=conf, db_session=db_session, msg=msg)
build = ModuleBuild.get_by_id(db_session, 3)
assert build.state == 1
assert build.name == "includemodule"
batches = {}
for comp_build in ComponentBuild.query.filter_by(module_id=3).all():
for comp_build in build.component_builds:
batches[comp_build.package] = comp_build.batch
assert batches["perl-List-Compare"] == 2
assert batches["perl-Tangerine"] == 2
@@ -183,7 +185,7 @@ class TestModuleInit:
@patch("module_build_service.scm.SCM")
@patch("module_build_service.utils.submit.get_build_arches", return_value=["x86_64"])
def test_init_when_get_latest_raises(
self, get_build_arches, mocked_scm, mocked_from_module_event):
self, get_build_arches, mocked_scm, mocked_from_module_event, db_session):
FakeSCM(
mocked_scm,
"testmodule",
@@ -193,12 +195,13 @@ class TestModuleInit:
)
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="init")
with make_session(conf) as session:
build = session.query(ModuleBuild).filter_by(id=2).one()
mocked_from_module_event.return_value = build
self.fn(config=conf, session=session, msg=msg)
# Query the database again to make sure the build object is updated
session.refresh(build)
# Make sure the module entered the failed state
assert build.state == 4, build.state
assert "Failed to get the latest commit for" in build.state_reason
build = ModuleBuild.get_by_id(db_session, 2)
mocked_from_module_event.return_value = build
self.fn(config=conf, db_session=db_session, msg=msg)
# Query the database again to make sure the build object is updated
db_session.refresh(build)
# Make sure the module entered the failed state
assert build.state == 4, build.state
assert "Failed to get the latest commit for" in build.state_reason

View File

@@ -27,7 +27,7 @@ import module_build_service.scheduler.handlers.modules
import os
import koji
import pytest
from tests import conf, db, scheduler_init_data, read_staged_data
from tests import conf, scheduler_init_data, read_staged_data
import module_build_service.resolver
from module_build_service import build_logs, Modulemd
from module_build_service.utils.general import load_mmd
@@ -44,7 +44,8 @@ class TestModuleWait:
def teardown_method(self, test_method):
try:
path = build_logs.path(1)
with module_build_service.models.make_db_session(conf) as db_session:
path = build_logs.path(db_session, 1)
os.remove(path)
except Exception:
pass
@@ -79,8 +80,8 @@ class TestModuleWait:
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=1, module_build_state="some state")
with patch.object(module_build_service.resolver, "system_resolver"):
self.fn(config=self.config, session=self.session, msg=msg)
with patch("module_build_service.resolver.GenericResolver.create"):
self.fn(config=self.config, db_session=self.session, msg=msg)
@patch(
"module_build_service.builder.GenericBuilder.default_buildroot_groups",
@@ -115,20 +116,19 @@ class TestModuleWait:
resolver.backend = "db"
resolver.get_module_tag.return_value = "module-testmodule-master-20170109091357"
with patch.object(module_build_service.resolver, "system_resolver", new=resolver):
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, session=db_session, msg=msg)
koji_session.newRepo.assert_called_once_with("module-123-build")
generic_resolver.create.return_value = resolver
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, db_session=db_session, msg=msg)
koji_session.newRepo.assert_called_once_with("module-123-build")
# When module-build-macros is reused, it still has to appear only
# once in database.
builds_count = (
db.session.query(ComponentBuild)
.filter_by(package="module-build-macros", module_id=2)
.count()
)
builds_count = db_session.query(ComponentBuild).filter_by(
package="module-build-macros", module_id=2).count()
assert builds_count == 1
@patch(
@@ -164,12 +164,14 @@ class TestModuleWait:
resolver.backend = "db"
resolver.get_module_tag.return_value = "module-testmodule-master-20170109091357"
with patch.object(module_build_service.resolver, "system_resolver", new=resolver):
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, session=db_session, msg=msg)
assert koji_session.newRepo.called
generic_resolver.create.return_value = resolver
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, db_session=db_session, msg=msg)
assert koji_session.newRepo.called
@patch(
"module_build_service.builder.GenericBuilder.default_buildroot_groups",
@@ -209,13 +211,15 @@ class TestModuleWait:
"module-bootstrap-tag": [base_mmd]
}
with patch.object(module_build_service.resolver, "system_resolver", new=resolver):
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, session=db_session, msg=msg)
module_build = ModuleBuild.query.filter_by(id=2).one()
assert module_build.cg_build_koji_tag == "modular-updates-candidate"
generic_resolver.create.return_value = resolver
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state")
module_build_service.scheduler.handlers.modules.wait(
config=conf, db_session=db_session, msg=msg)
module_build = ModuleBuild.get_by_id(db_session, 2)
assert module_build.cg_build_koji_tag == "modular-updates-candidate"
@pytest.mark.parametrize(
"koji_cg_tag_build,expected_cg_koji_build_tag",
@@ -280,12 +284,12 @@ class TestModuleWait:
"koji_cg_tag_build",
new=koji_cg_tag_build,
):
with patch.object(module_build_service.resolver, "system_resolver", new=resolver):
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state"
)
module_build_service.scheduler.handlers.modules.wait(
config=conf, session=db_session, msg=msg
)
module_build = ModuleBuild.query.filter_by(id=2).one()
assert module_build.cg_build_koji_tag == expected_cg_koji_build_tag
generic_resolver.create.return_value = resolver
msg = module_build_service.messaging.MBSModule(
msg_id=None, module_build_id=2, module_build_state="some state"
)
module_build_service.scheduler.handlers.modules.wait(
config=conf, db_session=db_session, msg=msg
)
module_build = ModuleBuild.get_by_id(db_session, 2)
assert module_build.cg_build_koji_tag == expected_cg_koji_build_tag

View File

@@ -22,7 +22,7 @@ import re
import pytest
from mock import patch
from module_build_service import models, conf
from tests import reuse_component_init_data, db, clean_database
from tests import clean_database
import mock
import koji
from module_build_service.scheduler.producer import MBSProducer
@@ -31,6 +31,7 @@ import six.moves.queue as queue
from datetime import datetime, timedelta
@pytest.mark.usefixtures("reuse_component_init_data")
@patch(
"module_build_service.builder.GenericBuilder.default_buildroot_groups",
return_value={"build": [], "srpm-build": []},
@@ -39,8 +40,6 @@ from datetime import datetime, timedelta
@patch("module_build_service.builder.GenericBuilder.create_from_module")
class TestPoller:
def setup_method(self, test_method):
reuse_component_init_data()
self.p_read_config = patch(
"koji.read_config",
return_value={
@@ -58,7 +57,7 @@ class TestPoller:
@pytest.mark.parametrize("fresh", [True, False])
@patch("module_build_service.utils.batches.start_build_component")
def test_process_paused_module_builds(
self, start_build_component, create_builder, global_consumer, dbg, fresh
self, start_build_component, create_builder, global_consumer, dbg, fresh, db_session
):
"""
Tests general use-case of process_paused_module_builds.
@@ -72,14 +71,14 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
# If fresh is set, then we simulate that activity just occurred 2 minutes ago on the build
if fresh:
module_build.time_modified = datetime.utcnow() - timedelta(minutes=2)
else:
module_build.time_modified = datetime.utcnow() - timedelta(days=5)
db.session.commit()
db_session.commit()
# Poll :)
hub = mock.MagicMock()
@@ -87,7 +86,7 @@ class TestPoller:
poller.poll()
# Refresh our module_build object.
module_build = models.ModuleBuild.query.get(3)
db_session.refresh(module_build)
# If fresh is set, we expect the poller to not touch the module build since it's been less
# than 10 minutes of inactivity
@@ -112,7 +111,7 @@ class TestPoller:
@patch("module_build_service.utils.batches.start_build_component")
def test_process_paused_module_builds_with_new_repo_task(
self, start_build_component, create_builder, global_consumer, dbg, task_state,
expect_start_build_component
expect_start_build_component, db_session
):
"""
Tests general use-case of process_paused_module_builds.
@@ -126,7 +125,7 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
module_build.time_modified = datetime.utcnow() - timedelta(days=5)
if task_state:
@@ -134,7 +133,7 @@ class TestPoller:
koji_session.getTaskInfo.return_value = {"state": task_state}
builder.koji_session = koji_session
module_build.new_repo_task_id = 123
db.session.commit()
db_session.commit()
# Poll :)
hub = mock.MagicMock()
@@ -142,7 +141,7 @@ class TestPoller:
poller.poll()
# Refresh our module_build object.
module_build = models.ModuleBuild.query.get(3)
db_session.refresh(module_build)
if expect_start_build_component:
expected_state = koji.BUILD_STATES["BUILDING"]
@@ -160,7 +159,7 @@ class TestPoller:
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_retrigger_new_repo_on_failure(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
"""
Tests that we call koji_sesion.newRepo when newRepo task failed.
@@ -180,10 +179,10 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
module_build.new_repo_task_id = 123456
db.session.commit()
db_session.commit()
hub = mock.MagicMock()
poller = MBSProducer(hub)
@@ -195,7 +194,7 @@ class TestPoller:
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_trigger_new_repo_when_succeeded(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
"""
Tests that we do not call koji_sesion.newRepo when newRepo task
@@ -216,23 +215,23 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
module_build.new_repo_task_id = 123456
db.session.commit()
db_session.commit()
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.poll()
# Refresh our module_build object.
module_build = models.ModuleBuild.query.get(3)
db_session.refresh(module_build)
assert not koji_session.newRepo.called
assert module_build.new_repo_task_id == 123456
def test_process_paused_module_builds_waiting_for_repo(
self, create_builder, global_consumer, dbg
self, create_builder, global_consumer, dbg, db_session
):
"""
Tests that process_paused_module_builds does not start new batch
@@ -247,10 +246,10 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
module_build.new_repo_task_id = 123456
db.session.commit()
db_session.commit()
# Poll :)
hub = mock.MagicMock()
@@ -258,7 +257,7 @@ class TestPoller:
poller.poll()
# Refresh our module_build object.
module_build = models.ModuleBuild.query.get(3)
db_session.refresh(module_build)
# Components should not be in building state
components = module_build.current_batch()
@@ -268,7 +267,7 @@ class TestPoller:
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_old_build_targets_are_not_associated_with_any_module_builds(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
consumer = mock.MagicMock()
consumer.incoming = queue.Queue()
@@ -283,16 +282,16 @@ class TestPoller:
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.delete_old_koji_targets(conf, db.session)
poller.delete_old_koji_targets(conf, db_session)
koji_session.deleteBuildTarget.assert_not_called()
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_dont_delete_base_module_build_target(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
koji_session = ClientSession.return_value
# No created module build has any of these tags.
@@ -308,16 +307,16 @@ class TestPoller:
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.delete_old_koji_targets(conf, db.session)
poller.delete_old_koji_targets(conf, db_session)
koji_session.deleteBuildTarget.assert_not_called()
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_dont_delete_build_target_for_unfinished_module_builds(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
koji_session = ClientSession.return_value
# No created module build has any of these tags.
@@ -331,31 +330,32 @@ class TestPoller:
# should not be deleted.
for state in ["init", "wait", "build"]:
module_build.state = state
db.session.commit()
db_session.commit()
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.delete_old_koji_targets(conf, db.session)
poller.delete_old_koji_targets(conf, db_session)
koji_session.deleteBuildTarget.assert_not_called()
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_only_delete_build_target_with_allowed_koji_tag_prefix(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
module_build_2 = models.ModuleBuild.query.filter_by(id=2).one()
module_build_3 = models.ModuleBuild.query.filter_by(id=3).one()
module_build_2 = models.ModuleBuild.get_by_id(db_session, 2)
# Only module build 1's build target should be deleted.
module_build_2.koji_tag = "module-tag1"
module_build_2.state = models.BUILD_STATES["done"]
# Ensure to exceed the koji_target_delete_time easily later for deletion
module_build_2.time_completed = datetime.utcnow() - timedelta(hours=24)
module_build_3 = models.ModuleBuild.get_by_id(db_session, 3)
module_build_3.koji_tag = "f28"
db.session.commit()
db.session.refresh(module_build_2)
db.session.refresh(module_build_3)
db_session.commit()
db_session.refresh(module_build_2)
db_session.refresh(module_build_3)
koji_session = ClientSession.return_value
# No created module build has any of these tags.
@@ -372,7 +372,7 @@ class TestPoller:
with patch.object(conf, "koji_target_delete_time", new=60):
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.delete_old_koji_targets(conf, db.session)
poller.delete_old_koji_targets(conf, db_session)
koji_session.deleteBuildTarget.assert_called_once_with(1)
koji_session.krb_login.assert_called_once()
@@ -380,17 +380,17 @@ class TestPoller:
@patch.dict("sys.modules", krbV=mock.MagicMock())
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_cant_delete_build_target_if_not_reach_delete_time(
self, ClientSession, create_builder, global_consumer, dbg
self, ClientSession, create_builder, global_consumer, dbg, db_session
):
module_build_2 = models.ModuleBuild.query.filter_by(id=2).one()
module_build_2 = models.ModuleBuild.get_by_id(db_session, 2)
# Only module build 1's build target should be deleted.
module_build_2.koji_tag = "module-tag1"
module_build_2.state = models.BUILD_STATES["done"]
# Ensure to exceed the koji_target_delete_time easily later for deletion
module_build_2.time_completed = datetime.utcnow() - timedelta(minutes=5)
db.session.commit()
db.session.refresh(module_build_2)
db_session.commit()
db_session.refresh(module_build_2)
koji_session = ClientSession.return_value
# No created module build has any of these tags.
@@ -407,12 +407,14 @@ class TestPoller:
# enough for test.
hub = mock.MagicMock()
poller = MBSProducer(hub)
poller.delete_old_koji_targets(conf, db.session)
poller.delete_old_koji_targets(conf, db_session)
koji_session.deleteBuildTarget.assert_not_called()
@pytest.mark.parametrize("state", ["init", "wait"])
def test_process_waiting_module_build(self, create_builder, global_consumer, dbg, state):
def test_process_waiting_module_build(
self, create_builder, global_consumer, dbg, state, db_session
):
""" Test that processing old waiting module builds works. """
consumer = mock.MagicMock()
@@ -424,27 +426,29 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.state = models.BUILD_STATES[state]
original = datetime.utcnow() - timedelta(minutes=11)
module_build.time_modified = original
db.session.commit()
db.session.refresh(module_build)
db_session.commit()
db_session.refresh(module_build)
# Ensure the queue is empty before we start.
assert consumer.incoming.qsize() == 0
# Poll :)
poller.process_waiting_module_builds(db.session)
poller.process_waiting_module_builds(db_session)
assert consumer.incoming.qsize() == 1
module_build = models.ModuleBuild.query.get(3)
db_session.refresh(module_build)
# ensure the time_modified was changed.
assert module_build.time_modified > original
@pytest.mark.parametrize("state", ["init", "wait"])
def test_process_waiting_module_build_not_old_enough(
self, create_builder, global_consumer, dbg, state
self, create_builder, global_consumer, dbg, state, db_session
):
""" Test that we do not process young waiting builds. """
@@ -457,23 +461,26 @@ class TestPoller:
# Change the batch to 2, so the module build is in state where
# it is not building anything, but the state is "build".
module_build = models.ModuleBuild.query.get(3)
module_build = models.ModuleBuild.get_by_id(db_session, 3)
module_build.state = models.BUILD_STATES[state]
original = datetime.utcnow() - timedelta(minutes=9)
module_build.time_modified = original
db.session.commit()
db.session.refresh(module_build)
db_session.commit()
db_session.refresh(module_build)
# Ensure the queue is empty before we start.
assert consumer.incoming.qsize() == 0
# Poll :)
poller.process_waiting_module_builds(db.session)
poller.process_waiting_module_builds(db_session)
# Ensure we did *not* process the 9 minute-old build.
assert consumer.incoming.qsize() == 0
def test_process_waiting_module_build_none_found(self, create_builder, global_consumer, dbg):
def test_process_waiting_module_build_none_found(
self, create_builder, global_consumer, dbg, db_session
):
""" Test nothing happens when no module builds are waiting. """
consumer = mock.MagicMock()
@@ -487,7 +494,7 @@ class TestPoller:
assert consumer.incoming.qsize() == 0
# Poll :)
poller.process_waiting_module_builds(db.session)
poller.process_waiting_module_builds(db_session)
# Ensure we did *not* process any of the non-waiting builds.
assert consumer.incoming.qsize() == 0
@@ -634,21 +641,23 @@ class TestPoller:
@pytest.mark.parametrize("btime", (True, False))
@patch("module_build_service.builder.KojiModuleBuilder.KojiClientSession")
def test_sync_koji_build_tags(
self, ClientSession, create_builder, global_consumer, dbg, tagged, tagged_in_final, btime
self, ClientSession, create_builder, global_consumer, dbg, tagged, tagged_in_final, btime,
db_session
):
module_build_2 = models.ModuleBuild.query.filter_by(id=2).one()
module_build_2 = models.ModuleBuild.get_by_id(db_session, 2)
# Only module build 1's build target should be deleted.
module_build_2.koji_tag = "module-tag1"
module_build_2.state = models.BUILD_STATES["build"]
if btime:
module_build_2.time_modified = datetime.utcnow() - timedelta(minutes=12)
c = module_build_2.current_batch()[0]
c.state = koji.BUILD_STATES["COMPLETE"]
c.tagged_in_final = False
c.tagged = False
db.session.commit()
db.session.refresh(module_build_2)
db_session.commit()
db_session.refresh(module_build_2)
koji_session = ClientSession.return_value
# No created module build has any of these tags.
@@ -668,7 +677,9 @@ class TestPoller:
poller = MBSProducer(hub)
assert consumer.incoming.qsize() == 0
poller.sync_koji_build_tags(conf, db.session)
poller.sync_koji_build_tags(conf, db_session)
assert consumer.incoming.qsize() == len(ret)
expected_msg_tags = []
@@ -714,18 +725,18 @@ class TestPoller:
mock_gw.return_value = greenwave_result
poller.poll_greenwave(conf, db.session)
poller.poll_greenwave(conf, db_session)
mock_gw.assert_called_once()
module = models.ModuleBuild.query.filter_by(state=models.BUILD_STATES["ready"]).all()
modules = models.ModuleBuild.by_state(db_session, "ready")
if greenwave_result:
assert len(module) == 2
assert set([m.id for m in module]) == {1, 2}
assert len(modules) == 2
assert set([m.id for m in modules]) == {1, 2}
else:
assert len(module) == 1
assert module[0].id == 1
module = models.ModuleBuild.query.filter_by(state=models.BUILD_STATES["done"]).all()
assert len(module) == 1
assert module[0].id == 2
assert re.match("Gating failed.*", module[0].state_reason)
assert len(modules) == 1
assert modules[0].id == 1
modules = models.ModuleBuild.by_state(db_session, "done")
assert len(modules) == 1
assert modules[0].id == 2
assert re.match("Gating failed.*", modules[0].state_reason)

View File

@@ -25,7 +25,8 @@ import mock
import module_build_service.messaging
import module_build_service.scheduler.handlers.repos
import module_build_service.models
from tests import conf, db, scheduler_init_data
from module_build_service.models import ComponentBuild
from tests import conf, scheduler_init_data
class TestRepoDone:
@@ -39,7 +40,8 @@ class TestRepoDone:
from_repo_done_event.return_value = None
msg = module_build_service.messaging.KojiRepoChange(
"no matches for this...", "2016-some-nonexistent-build")
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
@mock.patch(
"module_build_service.builder.KojiModuleBuilder."
@@ -76,7 +78,8 @@ class TestRepoDone:
msg = module_build_service.messaging.KojiRepoChange(
"some_msg_id", "module-testmodule-master-20170109091357-7c29193d-build")
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
build_fn.assert_called_once_with(
artifact_name="tangerine",
source=(
@@ -137,7 +140,8 @@ class TestRepoDone:
msg = module_build_service.messaging.KojiRepoChange(
"some_msg_id", "module-testmodule-master-20170109091357-7c29193d-build")
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
finalizer.assert_called_once()
@@ -177,7 +181,8 @@ class TestRepoDone:
msg = module_build_service.messaging.KojiRepoChange(
"some_msg_id", "module-testmodule-master-20170109091357-7c29193d-build")
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
build_fn.assert_called_once_with(
artifact_name="tangerine",
source=(
@@ -196,14 +201,17 @@ class TestRepoDone:
complete or go to the next build batch.
"""
scheduler_init_data(db_session, 1)
component_build = db_session.query(ComponentBuild).filter_by(package="tangerine").one()
component_build.tagged = False
db_session.commit()
msg = module_build_service.messaging.KojiRepoChange(
"some_msg_id", "module-testmodule-master-20170109091357-7c29193d-build")
component_build = (
module_build_service.models.ComponentBuild.query.filter_by(package="tangerine").one())
component_build.tagged = False
db.session.add(component_build)
db.session.commit()
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
mock_log_info.assert_called_with(
"Ignoring repo regen, because not all components are tagged."
)
@@ -241,7 +249,8 @@ class TestRepoDone:
msg = module_build_service.messaging.KojiRepoChange(
"some_msg_id", "module-testmodule-master-20170109091357-7c29193d-build")
module_build_service.scheduler.handlers.repos.done(config=conf, session=db_session, msg=msg)
module_build_service.scheduler.handlers.repos.done(
config=conf, db_session=db_session, msg=msg)
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 2)
assert module_build.state == module_build_service.models.BUILD_STATES["failed"]

View File

@@ -21,25 +21,24 @@
# Written by Jan Kaluza <jkaluza@redhat.com>
import mock
import pytest
from mock import patch
import module_build_service.messaging
import module_build_service.scheduler.handlers.repos
import module_build_service.scheduler.handlers.tags
import module_build_service.models
from tests import reuse_component_init_data
from tests import conf, db
from tests import conf
import koji
import pytest
@pytest.mark.usefixtures("reuse_component_init_data")
class TestTagTagged:
def setup_method(self, test_method):
reuse_component_init_data()
@mock.patch("module_build_service.models.ModuleBuild.from_tag_change_event")
def test_no_matching_module(self, from_tag_change_event):
def test_no_matching_module(self, from_tag_change_event, db_session):
""" Test that when a tag msg hits us and we have no match,
that we do nothing gracefully.
"""
@@ -47,9 +46,9 @@ class TestTagTagged:
msg = module_build_service.messaging.KojiTagChange(
"no matches for this...", "2016-some-nonexistent-build", "artifact", "artifact-1.2-1")
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
def test_no_matching_artifact(self):
def test_no_matching_artifact(self, db_session):
""" Test that when a tag msg hits us and we have no match,
that we do nothing gracefully.
"""
@@ -60,7 +59,7 @@ class TestTagTagged:
"artifact-1.2-1",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
@patch(
"module_build_service.builder.GenericBuilder.default_buildroot_groups",
@@ -68,7 +67,7 @@ class TestTagTagged:
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo(self, create_builder, koji_get_session, dbg):
def test_newrepo(self, create_builder, koji_get_session, dbg, db_session):
"""
Test that newRepo is called in the expected times.
"""
@@ -86,7 +85,7 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
# Set previous components as COMPLETE and tagged.
module_build.batch = 1
@@ -102,7 +101,8 @@ class TestTagTagged:
elif c.package == "perl-List-Compare":
c.nvr = "perl-List-Compare-0.53-5.module+0+d027b723"
c.state = koji.BUILD_STATES["COMPLETE"]
db.session.commit()
db_session.commit()
# Tag the first component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -112,7 +112,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg
config=conf, db_session=db_session, msg=msg
)
# Tag the first component to the final tag.
msg = module_build_service.messaging.KojiTagChange(
@@ -122,7 +122,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg
config=conf, db_session=db_session, msg=msg
)
# newRepo should not be called, because there are still components
@@ -137,7 +137,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg
config=conf, db_session=db_session, msg=msg
)
# newRepo should not be called, because the component has not been
@@ -152,15 +152,14 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should be called now - all components have been tagged.
koji_session.newRepo.assert_called_once_with(
"module-testmodule-master-20170219191323-c40c156c-build")
# Refresh our module_build object.
db.session.expunge(module_build)
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
db_session.refresh(module_build)
# newRepo task_id should be stored in database, so we can check its
# status later in poller.
@@ -172,7 +171,9 @@ class TestTagTagged:
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo_still_building_components(self, create_builder, koji_get_session, dbg):
def test_newrepo_still_building_components(
self, create_builder, koji_get_session, dbg, db_session
):
"""
Test that newRepo is called in the expected times.
"""
@@ -190,13 +191,14 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
component = module_build_service.models.ComponentBuild.query.filter_by(
component = db_session.query(module_build_service.models.ComponentBuild).filter_by(
package="perl-Tangerine", module_id=module_build.id).one()
component.state = koji.BUILD_STATES["BUILDING"]
component.nvr = "perl-Tangerine-0.23-1.module+0+d027b723"
db.session.commit()
db_session.commit()
# Tag the perl-List-Compare component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -206,7 +208,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the perl-List-Compare component to final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -215,7 +217,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should not be called, because perl-List-Compare has not been
# built yet.
@@ -227,7 +229,7 @@ class TestTagTagged:
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo_failed_components(self, create_builder, koji_get_session, dbg):
def test_newrepo_failed_components(self, create_builder, koji_get_session, dbg, db_session):
"""
Test that newRepo is called in the expected times.
"""
@@ -245,7 +247,7 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
# Set previous components as COMPLETE and tagged.
module_build.batch = 1
@@ -255,15 +257,18 @@ class TestTagTagged:
c.tagged_in_final = True
module_build.batch = 2
component = module_build_service.models.ComponentBuild.query.filter_by(
component = db_session.query(module_build_service.models.ComponentBuild).filter_by(
package="perl-Tangerine", module_id=module_build.id).one()
component.state = koji.BUILD_STATES["FAILED"]
component.nvr = "perl-Tangerine-0.23-1.module+0+d027b723"
component = module_build_service.models.ComponentBuild.query.filter_by(
component = db_session.query(module_build_service.models.ComponentBuild).filter_by(
package="perl-List-Compare", module_id=module_build.id).one()
component.state = koji.BUILD_STATES["COMPLETE"]
component.nvr = "perl-List-Compare-0.53-5.module+0+d027b723"
db.session.commit()
db_session.commit()
# Tag the perl-List-Compare component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -273,7 +278,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg
config=conf, db_session=db_session, msg=msg
)
# Tag the perl-List-Compare component to final tag.
msg = module_build_service.messaging.KojiTagChange(
@@ -283,7 +288,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should be called now - all successfully built
# components have been tagged.
@@ -291,8 +296,7 @@ class TestTagTagged:
"module-testmodule-master-20170219191323-c40c156c-build")
# Refresh our module_build object.
db.session.expunge(module_build)
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
db_session.refresh(module_build)
# newRepo task_id should be stored in database, so we can check its
# status later in poller.
@@ -304,7 +308,9 @@ class TestTagTagged:
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo_multiple_batches_tagged(self, create_builder, koji_get_session, dbg):
def test_newrepo_multiple_batches_tagged(
self, create_builder, koji_get_session, dbg, db_session
):
"""
Test that newRepo is called just once and only when all components
are tagged even if we tag components from the multiple batches in the
@@ -324,19 +330,21 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
module_build.batch = 2
mbm = module_build_service.models.ComponentBuild.query.filter_by(
mbm = db_session.query(module_build_service.models.ComponentBuild).filter_by(
module_id=3, package="module-build-macros").one()
mbm.tagged = False
db.session.add(mbm)
for c in module_build.current_batch():
if c.package == "perl-Tangerine":
c.nvr = "perl-Tangerine-0.23-1.module+0+d027b723"
elif c.package == "perl-List-Compare":
c.nvr = "perl-List-Compare-0.53-5.module+0+d027b723"
c.state = koji.BUILD_STATES["COMPLETE"]
db.session.commit()
db_session.commit()
# Tag the first component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -346,7 +354,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the first component to the final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -355,7 +363,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should not be called, because there are still components
# to tag.
@@ -369,7 +377,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the second component to final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -378,7 +386,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should not be called, because there are still components
# to tag.
@@ -392,7 +400,7 @@ class TestTagTagged:
"module-build-macros-0.1-1.module+0+b0a1d1f7",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the component from first batch to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -401,15 +409,14 @@ class TestTagTagged:
"module-build-macros-0.1-1.module+0+b0a1d1f7",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should be called now - all components have been tagged.
koji_session.newRepo.assert_called_once_with(
"module-testmodule-master-20170219191323-c40c156c-build")
# Refresh our module_build object.
db.session.expunge(module_build)
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
db_session.refresh(module_build)
# newRepo task_id should be stored in database, so we can check its
# status later in poller.
@@ -421,7 +428,7 @@ class TestTagTagged:
)
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo_build_time_only(self, create_builder, koji_get_session, dbg):
def test_newrepo_build_time_only(self, create_builder, koji_get_session, dbg, db_session):
"""
Test the component.build_time_only is respected in tag handler.
"""
@@ -439,7 +446,7 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
# Set previous components as COMPLETE and tagged.
module_build.batch = 1
@@ -451,18 +458,20 @@ class TestTagTagged:
c.tagged_in_final = True
module_build.batch = 2
component = module_build_service.models.ComponentBuild.query.filter_by(
component = db_session.query(module_build_service.models.ComponentBuild).filter_by(
package="perl-Tangerine", module_id=module_build.id).one()
component.state = koji.BUILD_STATES["COMPLETE"]
component.build_time_only = True
component.tagged = False
component.tagged_in_final = False
component.nvr = "perl-Tangerine-0.23-1.module+0+d027b723"
component = module_build_service.models.ComponentBuild.query.filter_by(
component = db_session.query(module_build_service.models.ComponentBuild).filter_by(
package="perl-List-Compare", module_id=module_build.id).one()
component.state = koji.BUILD_STATES["COMPLETE"]
component.nvr = "perl-List-Compare-0.53-5.module+0+d027b723"
db.session.commit()
db_session.commit()
# Tag the perl-Tangerine component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -472,7 +481,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
assert not koji_session.newRepo.called
# Tag the perl-List-Compare component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -482,7 +491,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the perl-List-Compare component to final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -491,7 +500,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# newRepo should be called now - all successfully built
# components have been tagged.
@@ -499,8 +508,7 @@ class TestTagTagged:
"module-testmodule-master-20170219191323-c40c156c-build")
# Refresh our module_build object.
db.session.expunge(module_build)
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
db_session.refresh(module_build)
# newRepo task_id should be stored in database, so we can check its
# status later in poller.
@@ -522,7 +530,7 @@ class TestTagTagged:
@patch("module_build_service.builder.KojiModuleBuilder.KojiModuleBuilder.get_session")
@patch("module_build_service.builder.GenericBuilder.create_from_module")
def test_newrepo_not_duplicated(
self, create_builder, koji_get_session, dbg, task_state, expect_new_repo
self, create_builder, koji_get_session, dbg, task_state, expect_new_repo, db_session
):
"""
Test that newRepo is not called if a task is already in progress.
@@ -541,7 +549,7 @@ class TestTagTagged:
}
create_builder.return_value = builder
module_build = module_build_service.models.ModuleBuild.query.get(3)
module_build = module_build_service.models.ModuleBuild.get_by_id(db_session, 3)
assert module_build
# Set previous components as COMPLETE and tagged.
@@ -562,7 +570,7 @@ class TestTagTagged:
if task_state is not None:
module_build.new_repo_task_id = 123456
db.session.commit()
db_session.commit()
# Tag the first component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
@@ -572,7 +580,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the first component to the final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -581,7 +589,7 @@ class TestTagTagged:
"perl-Tangerine-0.23-1.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the second component to the buildroot.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -590,7 +598,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# Tag the second component to the final tag.
msg = module_build_service.messaging.KojiTagChange(
"id",
@@ -599,7 +607,7 @@ class TestTagTagged:
"perl-List-Compare-0.53-5.module+0+d027b723",
)
module_build_service.scheduler.handlers.tags.tagged(
config=conf, session=db.session, msg=msg)
config=conf, db_session=db_session, msg=msg)
# All components are tagged, newRepo should be called if there are no active tasks.
if expect_new_repo:
@@ -609,8 +617,7 @@ class TestTagTagged:
assert not koji_session.newRepo.called
# Refresh our module_build object.
db.session.expunge(module_build)
module_build = module_build_service.models.ModuleBuild.query.filter_by(id=3).one()
db_session.refresh(module_build)
# newRepo task_id should be stored in database, so we can check its
# status later in poller.