Skip to content

Commit

Permalink
add_test
Browse files Browse the repository at this point in the history
  • Loading branch information
tdesveaux committed Jun 7, 2024
1 parent 9794f8c commit 1474639
Showing 1 changed file with 140 additions and 0 deletions.
140 changes: 140 additions & 0 deletions master/buildbot/test/integration/test_process_botmaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@
from twisted.internet import defer

from buildbot.config import BuilderConfig
from buildbot.data import resultspec
from buildbot.process.factory import BuildFactory
from buildbot.process.results import SKIPPED
from buildbot.process.results import SUCCESS
from buildbot.process.workerforbuilder import PingException
from buildbot.schedulers import triggerable
from buildbot.steps import trigger
from buildbot.test.fake.worker import WorkerController
from buildbot.test.util.integration import RunFakeMasterTestCase

Expand Down Expand Up @@ -57,3 +62,138 @@ def test_terminates_ping_on_shutdown_quick_mode(self):

def test_terminates_ping_on_shutdown_slow_mode(self):
return self.do_terminates_ping_on_shutdown(quick_mode=False)

async def test_shutdown_busy_with_child(self):
"""
Test that clean shutdown complete correctly
even when a running Build trigger another
and wait for it's completion
"""

parent_controller = WorkerController(self, 'parent_worker')
child_controller = WorkerController(self, 'child_worker')

config_dict = {
'builders': [
BuilderConfig(
name="parent",
workernames=[parent_controller.worker.name],
factory=BuildFactory([
trigger.Trigger(schedulerNames=['triggerable'], waitForFinish=True)
]),
),
BuilderConfig(
name="child", workernames=[child_controller.worker.name], factory=BuildFactory()
),
],
'workers': [parent_controller.worker, child_controller.worker],
'schedulers': [triggerable.Triggerable(name='triggerable', builderNames=['child'])],
'protocols': {'null': {}},
'multiMaster': True,
'collapseRequests': False,
}
await self.setup_master(config_dict)

parent_builder_id = await self.master.data.updates.findBuilderId('parent')
child_builder_id = await self.master.data.updates.findBuilderId('child')

await parent_controller.connect_worker()
# Pause worker of Child builder so we know the build won't start before we start shutdown
await child_controller.disconnect_worker()

# Create a Child build without Parent so we can later make sure it was not executed
_, first_child_brids = await self.create_build_request([child_builder_id])
self.assertEqual(len(first_child_brids), 1)

_, _parent_brids = await self.create_build_request([parent_builder_id])
self.assertEqual(len(_parent_brids), 1)
parent_brid = _parent_brids[parent_builder_id]

WAIT_TIMEOUT_SECONDS = 5
WAIT_STEP_SECONDS = 0.1

def _wait_step():
for _ in range(0, int(WAIT_TIMEOUT_SECONDS * 1000), int(WAIT_STEP_SECONDS * 1000)):
self.reactor.advance(WAIT_STEP_SECONDS)
yield

# wait until Parent trigger it's Child build
parent_buildid = None
for _ in _wait_step():
builds = await self.master.data.get(
("builds",),
filters=[resultspec.Filter('buildrequestid', 'eq', [parent_brid])],
)
if builds:
self.assertEqual(len(builds), 1)
parent_buildid = builds[0]['buildid']
break
self.assertIsNotNone(parent_buildid)

# now get the child_buildset
child_buildsetid = None
for _ in _wait_step():
buildsets = await self.master.data.get(
("buildsets",),
filters=[resultspec.Filter('parent_buildid', 'eq', [parent_buildid])],
)
if buildsets:
self.assertEqual(len(buildsets), 1)
child_buildsetid = buildsets[0]['bsid']
break
self.assertIsNotNone(child_buildsetid)

# and finally, the child BuildReques
child_buildrequest = None
for _ in _wait_step():
buildrequests = await self.master.data.get(
("buildrequests",),
filters=[resultspec.Filter('buildsetid', 'eq', [child_buildsetid])],
)
if buildrequests:
self.assertEqual(len(buildrequests), 1)
child_buildrequest = buildrequests[0]
break
self.assertIsNotNone(child_buildrequest)

# create a second Child without Parent for good mesure
_, second_child_brids = await self.create_build_request([child_builder_id])
self.assertEqual(len(second_child_brids), 1)

# Now start the clean shutdown
shutdown_deferred: defer.Deferred[None] = self.master.botmaster.cleanShutdown(
quickMode=False,
stopReactor=False,
)

# Connect back Child worker so the build can happen
await child_controller.connect_worker()

# wait for the child request to be claimed, and completed
for _ in _wait_step():
if child_buildrequest['claimed'] and child_buildrequest['complete']:
break
child_buildrequest = await self.master.data.get(
("buildrequests", child_buildrequest['buildrequestid']),
)
self.assertIsNotNone(child_buildrequest)
self.assertEqual(child_buildrequest['results'], SUCCESS)

# make sure parent-less BuildRequest weren't built
first_child_request = await self.master.data.get(
("buildrequests", first_child_brids[child_builder_id]),
)
self.assertIsNotNone(first_child_request)
self.assertFalse(first_child_request['claimed'])
self.assertFalse(first_child_request['complete'])

second_child_request = await self.master.data.get(
("buildrequests", second_child_brids[child_builder_id]),
)
self.assertIsNotNone(second_child_request)
self.assertFalse(second_child_request['claimed'])
self.assertFalse(second_child_request['complete'])

# confirm Master shutdown
await shutdown_deferred
self.assertTrue(shutdown_deferred.called)

0 comments on commit 1474639

Please sign in to comment.