def test_runrelease_two_webhooks(self): """ After a release, we call all configured webhooks. """ wc = WebhookCatcher(self) yield wc.start() repo = self.mkrepo('sideloader') yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.runInsert( 'sideloader_webhook', dictmerge(WEBHOOK_QA_1, url=wc.url("h1"))) yield self.runInsert( 'sideloader_webhook', dictmerge(WEBHOOK_QA_2, url=wc.url("h2"))) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) r1 = yield wc.get_request() r2 = yield wc.get_request() [hook_req1, hook_req2] = sorted([r1, r2], key=lambda r: r.path) assert hook_req1.method == WEBHOOK_QA_1['method'] assert hook_req1.path == "/h1" assert hook_req2.method == WEBHOOK_QA_2['method'] assert hook_req2.path == "/h2" webhooks = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) [wh1, wh2] = id_sorted(webhooks) assert wh1['last_response'] == '' assert wh2['last_response'] == '' wc.reply(hook_req1, "Content.") wc.reply(hook_req2, "Joyous.") # Wait a bit for things to happen. yield self.wait(0.01) webhooks = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) [wh1, wh2] = id_sorted(webhooks) assert wh1['last_response'] == "Content." assert wh2['last_response'] == "Joyous."
def test_runrelease_two_webhooks(self): """ After a release, we call all configured webhooks. """ wc = WebhookCatcher(self) yield wc.start() repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.runInsert('sideloader_webhook', dictmerge(WEBHOOK_QA_1, url=wc.url("h1"))) yield self.runInsert('sideloader_webhook', dictmerge(WEBHOOK_QA_2, url=wc.url("h2"))) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) r1 = yield wc.get_request() r2 = yield wc.get_request() [hook_req1, hook_req2] = sorted([r1, r2], key=lambda r: r.path) assert hook_req1.method == WEBHOOK_QA_1['method'] assert hook_req1.path == "/h1" assert hook_req2.method == WEBHOOK_QA_2['method'] assert hook_req2.path == "/h2" webhooks = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) [wh1, wh2] = id_sorted(webhooks) assert wh1['last_response'] == '' assert wh2['last_response'] == '' wc.reply(hook_req1, "Content.") wc.reply(hook_req2, "Joyous.") # Wait a bit for things to happen. yield self.wait(0.01) webhooks = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) [wh1, wh2] = id_sorted(webhooks) assert wh1['last_response'] == "Content." assert wh2['last_response'] == "Joyous."
def test_build_and_autorelease(self): """ We can successfully build a simple project and have it automatically released. Note that this only creates the release object in the database. It doesn't actually run the release. """ repo = self.mkrepo('sideloader') yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 1) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['flow_id'], RELEASEFLOW_QA['id']) self.assertEqual(release['scheduled'], None) self.assertEqual(release['waiting'], True)
def test_build_and_release_timezone(self): """ When we build a release, we send the timestamp in UTC. The twisted database stuff assumes timezones are in UTC and sends them to postgres with an explicit zero offset. """ repo = self.mkrepo('sideloader') yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_PROD]) start = datetime.utcnow() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 1) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self.plug.call_release( {'build_id': 1, 'flow_id': RELEASEFLOW_PROD['id']}) [release] = yield self.plug.db._release.values() end = datetime.utcnow() self.assert_time_between( start, end, release['release_date'], 'release_date')
def test_build_and_release_timezone(self): """ When we build a release, we send the timestamp in UTC. The twisted database stuff assumes timezones are in UTC and sends them to postgres with an explicit zero offset. """ repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_PROD]) start = datetime.utcnow() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 1) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self.plug.call_release({ 'build_id': 1, 'flow_id': RELEASEFLOW_PROD['id'] }) [release] = yield self.plug.db._release.values() end = datetime.utcnow() self.assert_time_between(start, end, release['release_date'], 'release_date')
def test_build_and_autorelease(self): """ We can successfully build a simple project and have it automatically released. Note that this only creates the release object in the database. It doesn't actually run the release. """ repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 1) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['flow_id'], RELEASEFLOW_QA['id']) self.assertEqual(release['scheduled'], None) self.assertEqual(release['waiting'], True)
def test_runrelease(self): """ We can successfully run a release. This first creates a build and a release in the database, then runs the release. """ repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], True) self.assertEqual(release['lock'], False) yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) # Wait for webhook processing, even though we don't have any. yield self.wait(0.002)
def test_runrelease(self): """ We can successfully run a release. This first creates a build and a release in the database, then runs the release. """ repo = self.mkrepo('sideloader') yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], True) self.assertEqual(release['lock'], False) yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) # Wait for webhook processing, even though we don't have any. yield self.wait(0.002)
def setup_db(self, project_def, build_number=1, flow_defs=()): yield self.runInsert('sideloader_releasestream', RELEASESTREAM_QA) yield self.runInsert('sideloader_releasestream', RELEASESTREAM_PROD) yield self.runInsert('sideloader_project', project_def) for flow_def in flow_defs: yield self.runInsert('sideloader_releaseflow', dictmerge( flow_def, project_id=project_def['id'])) yield self.runInsert('sideloader_build', BUILD_1) if build_number is not None: yield self.plug.db.setBuildNumber( 'sideloader', build_number, create=True)
def setup_db(self, project_def, build_number=1, flow_defs=()): yield self.runInsert('sideloader_releasestream', RELEASESTREAM_QA) yield self.runInsert('sideloader_releasestream', RELEASESTREAM_PROD) yield self.runInsert('sideloader_project', project_def) for flow_def in flow_defs: yield self.runInsert( 'sideloader_releaseflow', dictmerge(flow_def, project_id=project_def['id'])) yield self.runInsert('sideloader_build', BUILD_1) if build_number is not None: yield self.plug.db.setBuildNumber('sideloader', build_number, create=True)
def test_runrelease_single_webhook(self): """ After a release, we call a configured webhook. """ wc = WebhookCatcher(self) yield wc.start() repo = self.mkrepo('sideloader') yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.runInsert( 'sideloader_webhook', dictmerge(WEBHOOK_QA_1, url=wc.url("h1"))) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) hook_req = yield wc.get_request() assert hook_req.method == WEBHOOK_QA_1['method'] assert hook_req.path == "/h1" [webhook] = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) assert webhook['last_response'] == '' wc.reply(hook_req, "Happy.") # Wait a bit for things to happen. yield self.wait(0.01) [webhook] = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) assert webhook['last_response'] == "Happy."
def test_runrelease_single_webhook(self): """ After a release, we call a configured webhook. """ wc = WebhookCatcher(self) yield wc.start() repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url), flow_defs=[RELEASEFLOW_QA]) yield self.runInsert('sideloader_webhook', dictmerge(WEBHOOK_QA_1, url=wc.url("h1"))) yield self.plug.call_build({'build_id': 1}) # FIXME: We dig directly into our fake db here, because we haven't # implemented FakeDB.getReleases() yet. self.assertEqual(self.plug.db._release, {}) yield self._wait_for_build(1) [release] = yield self.plug.db._release.values() yield self.plug.call_runrelease({'release_id': release['id']}) [release] = yield self.plug.db._release.values() self.assertEqual(release['build_id'], 1) self.assertEqual(release['waiting'], False) self.assertEqual(release['lock'], False) hook_req = yield wc.get_request() assert hook_req.method == WEBHOOK_QA_1['method'] assert hook_req.path == "/h1" [webhook] = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) assert webhook['last_response'] == '' wc.reply(hook_req, "Happy.") # Wait a bit for things to happen. yield self.wait(0.01) [webhook] = yield self.plug.db.getWebhooks(RELEASEFLOW_QA['id']) assert webhook['last_response'] == "Happy."
def test_build_bad_url(self): """ If we have a bad URL, the build fails. """ yield self.setup_db(dictmerge( PROJECT_SIDELOADER, github_url='This is not a valid URL.')) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> failed", ])
def test_build_missing_scripts(self): """ If the build and postinst scripts are missing, the build fails. """ repo = self.mkrepo('sideloader', add_scripts=False) yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url)) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> started for branch develop", "projects/build/view/1|#1> failed", ])
def test_build_bad_url(self): """ If we have a bad URL, the build fails. """ yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url='This is not a valid URL.')) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> failed", ])
def test_build(self): """ We can successfully build a simple project. """ repo = self.mkrepo('sideloader') yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url)) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 1) self.assertEqual(build['build_file'], 'test-package_0.2_amd64.deb') self.assert_notifications(notifications, [ "projects/build/view/1|#1> started for branch develop", "projects/build/view/1|#1> successful", ])
def test_build_missing_branch(self): """ If the branch we want to build doesn't exist, the build fails. """ repo = self.mkrepo('sideloader', add_scripts=False) yield self.setup_db(dictmerge( PROJECT_SIDELOADER, github_url=repo.url, branch='stormdamage')) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> started for branch stormdamage", "projects/build/view/1|#1> failed", ])
def test_build_bad_script(self): """ If the build script fails, the build fails. """ repo = self.mkrepo('sideloader') repo.add_file("scripts/test_build.sh", "exit 1", executable=True) repo.commit("Break build.") yield self.setup_db(dictmerge(PROJECT_SIDELOADER, github_url=repo.url)) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> started for branch develop", "projects/build/view/1|#1> failed", ])
def test_createRelease_getRelease(self): """ We can create a release and then get it. """ yield self.db.runInsert('sideloader_releasestream', RELEASESTREAM_QA) yield self.db.runInsert('sideloader_project', PROJECT_SIDELOADER) yield self.db.runInsert('sideloader_releaseflow', RELEASEFLOW_QA) yield self.db.runInsert('sideloader_build', BUILD_1) release_data = { 'flow_id': 1, 'build_id': 1, 'waiting': True, 'scheduled': None, 'release_date': now_utc(), 'lock': False, } [release_id] = yield self.db.createRelease(release_data) release = yield self.db.getRelease(release_id) self.assertEqual(release, dictmerge(release_data, id=release_id))
def test_build_missing_branch(self): """ If the branch we want to build doesn't exist, the build fails. """ repo = self.mkrepo('sideloader', add_scripts=False) yield self.setup_db( dictmerge(PROJECT_SIDELOADER, github_url=repo.url, branch='stormdamage')) notifications = self.patch_notifications() yield self.plug.call_build({'build_id': 1}) build = yield self._wait_for_build(1) self.assertEqual(build['state'], 2) self.assertEqual(build['build_file'], '') self.assert_notifications(notifications, [ "projects/build/view/1|#1> started for branch stormdamage", "projects/build/view/1|#1> failed", ])