6
6
from unittest import TestLoader
9
from canonical.testing import (LaunchpadZopelessLayer)
8
from canonical.testing import LaunchpadZopelessLayer
11
10
from canonical.config import config
12
from canonical.codehosting.jobs import JobRunner
11
from lp.services.job.runner import JobRunner
13
12
from lp.code.model.branchjob import RevisionMailJob
14
13
from canonical.launchpad.interfaces import (
15
14
BranchSubscriptionNotificationLevel,
17
16
from canonical.launchpad.database.diff import StaticDiff
18
17
from lp.code.interfaces.branchsubscription import (
19
18
BranchSubscriptionDiffSize,)
20
from canonical.launchpad.interfaces.job import JobStatus
21
from lp.testing.mail_helpers import pop_notifications
22
19
from lp.testing import TestCaseWithFactory
23
from canonical.launchpad.webapp import errorlog
26
class TestJobRunner(TestCaseWithFactory):
27
"""Ensure JobRunner behaves as expected."""
22
class TestRevisionMailJob(TestCaseWithFactory):
23
"""Ensure RevisionMailJob behaves as expected."""
29
25
layer = LaunchpadZopelessLayer
31
def makeBranchAndJobs(self):
32
"""Test fixture. Create a branch and two jobs that use it."""
33
branch = self.factory.makeBranch()
34
branch.subscribe(branch.registrant,
35
BranchSubscriptionNotificationLevel.FULL,
36
BranchSubscriptionDiffSize.WHOLEDIFF,
37
CodeReviewNotificationLevel.FULL)
38
job_1 = RevisionMailJob.create(
39
branch, 0, 'from@example.org', 'body', False, 'foo')
40
job_2 = RevisionMailJob.create(
41
branch, 1, 'from@example.org', 'body', False, 'bar')
42
LaunchpadZopelessLayer.txn.commit()
43
LaunchpadZopelessLayer.switchDbUser(config.sendbranchmail.dbuser)
44
return branch, job_1, job_2
46
def test_runJob(self):
47
"""Ensure status is set to completed when a job runs to completion."""
48
branch, job_1, job_2 = self.makeBranchAndJobs()
49
runner = JobRunner(job_1)
51
self.assertEqual(JobStatus.COMPLETED, job_1.job.status)
52
self.assertEqual([job_1], runner.completed_jobs)
54
27
def test_runJob_generates_diff(self):
55
28
"""Ensure that a diff is actually generated in this environment."""
56
29
self.useBzrBranches()
73
46
from_revision_id='null:', to_revision_id=to_revision_id)
74
47
self.assertIsNot(None, existing_diff)
76
def test_runAll(self):
77
"""Ensure runAll works in the normal case."""
78
branch, job_1, job_2 = self.makeBranchAndJobs()
79
runner = JobRunner([job_1, job_2])
81
self.assertEqual(JobStatus.COMPLETED, job_1.job.status)
82
self.assertEqual(JobStatus.COMPLETED, job_2.job.status)
83
(mail1, mail2) = pop_notifications()
85
set(['foo', 'bar']), set([mail1['Subject'], mail2['Subject']]))
86
self.assertEqual([job_1, job_2], runner.completed_jobs)
88
def test_runAll_skips_lease_failures(self):
89
"""Ensure runAll skips jobs whose leases can't be acquired."""
90
last_oops = errorlog.globalErrorUtility.getLastOopsReport()
91
branch, job_1, job_2 = self.makeBranchAndJobs()
92
job_2.job.acquireLease()
93
runner = JobRunner([job_1, job_2])
95
self.assertEqual(JobStatus.COMPLETED, job_1.job.status)
96
self.assertEqual(JobStatus.WAITING, job_2.job.status)
97
self.assertEqual([job_1], runner.completed_jobs)
98
self.assertEqual([job_2], runner.incomplete_jobs)
99
new_last_oops = errorlog.globalErrorUtility.getLastOopsReport()
100
self.assertEqual(last_oops.id, new_last_oops.id)
102
def test_runAll_reports_oopses(self):
103
"""When an error is encountered, report an oops and continue."""
104
branch, job_1, job_2 = self.makeBranchAndJobs()
106
# Ensure that jobs which call transaction.abort work, too.
108
raise Exception('Fake exception. Foobar, I say!')
109
job_1.run = raiseError
110
runner = JobRunner([job_1, job_2])
112
self.assertEqual([job_2], runner.completed_jobs)
113
self.assertEqual([job_1], runner.incomplete_jobs)
114
self.assertEqual([], list(RevisionMailJob.iterReady()))
115
self.assertEqual(JobStatus.FAILED, job_1.job.status)
116
self.assertEqual(JobStatus.COMPLETED, job_2.job.status)
117
reporter = errorlog.globalErrorUtility
118
oops = reporter.getLastOopsReport()
119
self.assertIn('Fake exception. Foobar, I say!', oops.tb_text)
123
51
return TestLoader().loadTestsFromName(__name__)