← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~sinzui/launchpad/question-email-2 into lp:launchpad

 

Curtis Hovey has proposed merging lp:~sinzui/launchpad/question-email-2 into lp:launchpad with lp:~sinzui/launchpad/question-email-1 as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #772682 in Launchpad itself: "Setup db and cron to process QuestionEmailJob "
  https://bugs.launchpad.net/launchpad/+bug/772682

For more details, see:
https://code.launchpad.net/~sinzui/launchpad/question-email-2/+merge/59433

QuestionEmailJob needs db permissions and possibly a cronscript configuration.

    Launchpad bug: https://bugs.launchpad.net/bugs/772682
    Pre-implementation: jcsackett, lifeless

QuestionEmailJob has been created but is tested or setup to run. This
branch does this.

--------------------------------------------------------------------

RULES

    * Update schema-lazr.conf to configure the job to run.
    * Reuse the answertracker user that sends question expirations.
      * Update the user with the job tables.
    * Add a test that verifies that the jobs will run as the correct user


QA

    * Create a question and link it to a bug and an faq
    * Use SQL to insert a job for that question into the QuestionJob table.
    * Run security.py to give the answertracker user access to jobs.
    * Ask an admin to run cronscripts/process-job-source-groups.py on
      qastaging.


LINT

    database/schema/security.cfg
    lib/canonical/config/schema-lazr.conf
    lib/lp/answers/configure.zcml
    lib/lp/answers/tests/test_questionjob.py


TEST

    ./bin/test -vv -t test_questionjob


IMPLEMENTATION

Added the jobs table to the answertracker db user.
Added the job to the config; the schema is correct for production
Added permissions to access the object.
Added a test that exercises the job cronscript and verifies the job can
complete.
    database/schema/security.cfg
    lib/canonical/config/schema-lazr.conf
    lib/lp/answers/configure.zcml
    lib/lp/answers/tests/test_questionjob.py
-- 
https://code.launchpad.net/~sinzui/launchpad/question-email-2/+merge/59433
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/question-email-2 into lp:launchpad.
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg	2011-04-21 14:01:20 +0000
+++ database/schema/security.cfg	2011-04-28 22:36:15 +0000
@@ -1232,6 +1232,7 @@
 public.distribution                     = SELECT
 public.faq                              = SELECT
 public.emailaddress                     = SELECT
+public.job                              = SELECT, UPDATE
 public.language                         = SELECT
 public.message                          = SELECT, INSERT
 public.messagechunk                     = SELECT, INSERT
@@ -1240,6 +1241,7 @@
 public.product                          = SELECT
 public.question                         = SELECT, UPDATE
 public.questionbug                      = SELECT
+public.questionjob                      = SELECT
 public.questionmessage                  = SELECT, INSERT
 public.questionsubscription             = SELECT
 public.sourcepackagename                = SELECT

=== modified file 'lib/canonical/config/schema-lazr.conf'
--- lib/canonical/config/schema-lazr.conf	2011-04-25 19:12:41 +0000
+++ lib/canonical/config/schema-lazr.conf	2011-04-28 22:36:15 +0000
@@ -2118,6 +2118,7 @@
     IMembershipNotificationJobSource,
     IPackageCopyJobSource,
     IPersonMergeJobSource,
+    IQuestionEmailJobSource
 
 [IMembershipNotificationJobSource]
 # This section is used by cronscripts/process-job-source.py.
@@ -2130,3 +2131,9 @@
 module: lp.registry.interfaces.persontransferjob
 dbuser: person-merge-job
 crontab_group: MAIN
+
+[IQuestionEmailJobSource]
+# This section is used by cronscripts/process-job-source.py.
+module: lp.answers.interfaces.questionjob
+dbuser: answertracker
+crontab_group: MAIN

=== modified file 'lib/lp/answers/configure.zcml'
--- lib/lp/answers/configure.zcml	2011-04-25 14:37:52 +0000
+++ lib/lp/answers/configure.zcml	2011-04-28 22:36:15 +0000
@@ -67,6 +67,16 @@
           />
     </class>
 
+    <class class=".model.questionjob.QuestionEmailJob">
+      <allow interface=".interfaces.questionjob.IQuestionEmailJob"/>
+    </class>
+
+    <securedutility
+        component=".model.questionjob.QuestionEmailJob"
+        provides=".interfaces.questionjob.IQuestionEmailJobSource">
+      <allow interface=".interfaces.questionjob.IQuestionEmailJobSource"/>
+    </securedutility>
+
     <!-- QuestionSubscription -->
     <class class=".model.questionsubscription.QuestionSubscription">
         <allow

=== modified file 'lib/lp/answers/tests/test_questionjob.py'
--- lib/lp/answers/tests/test_questionjob.py	2011-04-28 22:36:12 +0000
+++ lib/lp/answers/tests/test_questionjob.py	2011-04-28 22:36:15 +0000
@@ -7,8 +7,12 @@
 
 import transaction
 
+from testtools.content import Content
+from testtools.content_type import UTF8_TEXT
+
 from zope.component import getUtility
 
+from canonical.launchpad.interfaces.lpstorm import IStore
 from canonical.launchpad.mail import format_address
 from canonical.launchpad.scripts import log
 from canonical.testing import DatabaseFunctionalLayer
@@ -16,14 +20,17 @@
     QuestionJobType,
     QuestionRecipientSet,
     )
+from lp.answers.interfaces.questionjob import IQuestionEmailJobSource
 from lp.answers.model.questionjob import (
     QuestionJob,
     QuestionEmailJob,
     )
+from lp.services.job.interfaces.job import JobStatus
 from lp.services.log.logger import BufferLogger
 from lp.services.mail import stub
 from lp.services.worlddata.interfaces.language import ILanguageSet
 from lp.testing import (
+    run_script,
     person_logged_in,
     TestCaseWithFactory,
     )
@@ -312,3 +319,27 @@
             logger.getLogBuffer().splitlines())
         transaction.commit()
         self.assertEqual(2, len(stub.test_emails))
+
+    def test_run_cronscript(self):
+        # The cronscript is configured: schema-lazr.conf and security.cfg.
+        question = self.factory.makeQuestion()
+        self.addAnswerContact(question)
+        user, subject, body, headers = self.makeUserSubjectBodyHeaders()
+        job = QuestionEmailJob.create(
+            question, user, QuestionRecipientSet.ASKER_SUBSCRIBER,
+            subject, body, headers)
+        transaction.commit()
+
+        out, err, exit_code = run_script(
+            "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" % (
+                IQuestionEmailJobSource.getName()))
+        self.addDetail("stdout", Content(UTF8_TEXT, lambda: out))
+        self.addDetail("stderr", Content(UTF8_TEXT, lambda: err))
+        self.assertEqual(0, exit_code)
+        message = (
+            'QuestionEmailJob has sent email for question %s.' % question.id)
+        self.assertTrue(
+            message in err,
+            'Cound not find "%s" in err log:\n%s.' % (message, err))
+        IStore(job.job).invalidate()
+        self.assertEqual(JobStatus.COMPLETED, job.job.status)