Commits

Anonymous committed ebb1d5d

Fixing a bug in the get_all_jobs manager that ignored multiple settings, now we can have multiple jobs with multiple settings with the same file source

  • Participants
  • Parent commits 760a7c6

Comments (0)

Files changed (2)

eeorganizer/models.py

 import logging
 
 from django.db import models
+from django.conf import settings
 from django.contrib.auth.models import User
-from django.conf import settings
 from django.contrib.sites.models import Site
 from django.core.mail import send_mail
 from django.template.loader import render_to_string
 JOB_THRESHOLD=hasattr(settings, 'JOB_THRESHOLD') and settings.JOB_THRESHOLD or 5
 
 class JobManager(models.Manager):
-    def get_all_jobs(self, source, creation_time):
+    def get_all_jobs(self, source, creation_time, possible_events=None):
         tdelta = datetime.timedelta(seconds=JOB_THRESHOLD)
-        return self.filter(source = source, 
+        if possible_events:
+            self = self.filter(setting__event__in = possible_events)
+        return self.filter(source = source,
                     creation_time__gte = creation_time - tdelta,
                     creation_time__lte = creation_time + tdelta)
 
     objects = JobManager()
 
     def get_related_jobs(self):
-        return Job.objects.get_all_jobs(self.source, self.creation_time)
-    
+        return Job.objects.get_all_jobs(self.source, self.creation_time,
+                                                self.setting.event_set.all())
+
     @models.permalink
     def get_absolute_url(self):
         return ('resubmit_job', (), {'id' : self.pk,})
-    
+
     def _success(self):
-        if self.reason == 'finish': 
+        if self.reason == 'finish':
             return True
         else:
             return False
     success = property(_success)
-    
+
     def __unicode__(self):
         return "%s -- %s" % (self.source, self.creation_time)
-    
+
     class Meta:
         ordering = ['-creation_time']
         unique_together = (('creation_time', 'output'),)
     settings = models.ManyToManyField("Setting")
 
     def email_success(self, jobs):
-        message = render_to_string('eeorganizer/email_success.html', 
+        message = render_to_string('eeorganizer/email_success.html',
             {'event' : self,
             'jobs' : jobs,
             'site' : Site.objects.get_current() })
         subject = "Success! %s processed %s" % (unicode(self), jobs[0].source)
         logger.info("Sending email %s to %s from %s" % (subject, self.email_users.all(), settings.DEFAULT_FROM_EMAIL))
-        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, 
+        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
                                     [u.email for u in self.email_users.all()])
 
     def email_failure(self, jobs, responses):
-        message = render_to_string('eeorganizer/email_failure.html', 
+        message = render_to_string('eeorganizer/email_failure.html',
             {'event' : self,
             'jobs' : jobs,
             'responses' : responses,
             'site' : Site.objects.get_current() })
         subject = "Unable to process %s for %s" % (unicode(self),jobs[0].source)
         logger.info("Sending email %s to %s from %s" % (subject, self.email_users.all(), settings.DEFAULT_FROM_EMAIL))
-        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, 
+        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
                                     [u.email for u in self.email_users.all()])
 
     class Meta:

eeorganizer/tests.py

 import os
 import time
 
+from django.core import mail
 from django.test import TestCase
 from django.test.client import Client
 
-from django.core import mail
-
 from eeorganizer import utils
-from eeorganizer.models import Setting, Job, Event, all_files_processed
+from eeorganizer.models import Event
+from eeorganizer.models import Job
+from eeorganizer.models import Setting
+from eeorganizer.models import all_files_processed
 
 FAKE_JOB_ATTRS = {
     'JOB_SETTING_NAME': 'test_job_setting.setting',
 class TestEEOrganizer(TestCase):
     def setUp(self):
         o = open(os.path.join(
-            os.path.dirname(__file__), 'fixtures', 'fake_encoded_file.mov'), 
+            os.path.dirname(__file__), 'fixtures', 'fake_encoded_file.mov'),
             'w')
         o.write('Fake media file created for tests')
         o.close()
         FAKE_JOB_ATTRS['JOB_CREATION_TIME'] = str(
                                     int(time.mktime(DATETIME.timetuple())))
         os.environ.update(FAKE_JOB_ATTRS)
-    
+
     def tearDown(self):
         fixture_file = os.path.join(
             os.path.dirname(__file__), 'fixtures', 'fake_encoded_file.mov')
         if os.path.exists(fixture_file):
             os.remove(fixture_file)
-    
+
     def test_util_job_creation(self):
         # Check and make sure none of the items are already in the db
         self.assertRaises(Job.DoesNotExist, Job.objects.get, \
                                         creation_time = DATETIME)
         self.assertRaises(Setting.DoesNotExist, Setting.objects.get, \
                                         name=os.environ['JOB_SETTING_NAME'])
-        
+
         # Create the new job
         new_job = utils.create_job()
-        
+
         # Check the values for the new job (they should match environ)
         self.assertEquals(new_job.source, os.environ['JOB_SOURCE_FILE'])
-        self.assertEquals(new_job.output, 
+        self.assertEquals(new_job.output,
                     os.environ['JOB_OUT_PATH'])
         self.assertTrue(new_job.success)
         self.assertEquals(time.mktime(new_job.creation_time.timetuple()), \
                                     float(os.environ['JOB_CREATION_TIME']))
         #mktime returns a float so convert the environ to that
-        
+
         # Make sure a setting was created
         new_setting = Setting.objects.get(setting=os.environ['JOB_SETTING_NAME'])
         self.assertEquals(new_setting, new_job.setting)
-    
+
     def test_bad_job(self):
         os.environ['JOB_REASON'] = 'FAILURE'
         new_job = utils.create_job()
         self.assertFalse(new_job.success)
-        
+
         new_setting = new_job.setting
-        
+
         new_event, created = Event.objects.get_or_create(name='Test Event')
         new_event.num_of_jobs = None
         new_event.settings.clear()
-        new_event.email_users.create(username="FredDurst",email="fred@durst.com") 
+        new_event.email_users.create(username="FredDurst",email="fred@durst.com")
         new_event.settings.add(new_setting)
         new_event.save()
 
         mail.outbox = []
         utils.check_event(new_job)
         self.assertEquals(len(mail.outbox), 1)
-        self.assertEquals(mail.outbox[0].subject, 
+        self.assertEquals(mail.outbox[0].subject,
                         'Unable to process Test Event for fake_raw_file.mov')
-        
-    
+
+
     def test_all_processed_signal(self):
         # A boolean checker to see the callback was called
         signal_func_ran = [False]
-        
+
         new_job = utils.create_job()
         new_setting = new_job.setting
         new_event, created = Event.objects.get_or_create(name='Test Event')
         new_event.settings.clear()
-        new_event.email_users.create(username="FredDurst",email="fred@durst.com") 
+        new_event.email_users.create(username="FredDurst",email="fred@durst.com")
         new_event.settings.add(new_setting)
         new_event.save()
 
             self.assertEquals(len(kwargs['jobs']),\
                                 sender.num_of_jobs or sender.settings.count())
             signal_func_ran[0] = True
-        
+
         all_files_processed.connect(signal_callback)
         mail.outbox = []
-        
+
         utils.check_event(new_job)
         self.assertTrue(signal_func_ran[0])
         # check that we got a success email
-        
+
         self.assertEquals(len(mail.outbox), 1)
-        self.assertEquals(mail.outbox[0].subject, 
+        self.assertEquals(mail.outbox[0].subject,
                             'Success! Test Event processed fake_raw_file.mov')
         mail.outbox = []
-        
+
         signal_func_ran[0] = False
         #increase the number of jobs and make sure there isn't any signal
         new_event.num_of_jobs = 2
         new_event.save()
-        
+
         utils.check_event(new_job)
         self.assertFalse(signal_func_ran[0])
-        
+
         # let's make sure it will actually work
         os.environ['JOB_OUT_PATH'] = os.path.join(
             os.path.dirname(__file__), 'fixtures', 'fake_encoded_file2.mov')
         utils.check_event(new_job)
         self.assertTrue(signal_func_ran[0])
         self.assertEquals(len(mail.outbox), 1)
-        self.assertEquals(mail.outbox[0].subject, 
+        self.assertEquals(mail.outbox[0].subject,
                             'Success! Test Event processed fake_raw_file.mov')
-    
+
+    def test_double_settings_same_file(self):
+        # A boolean checker to see the callback was called
+        signal_func_ran = [False]
+
+        new_job = utils.create_job()
+        new_setting = new_job.setting
+        new_event, created = Event.objects.get_or_create(name='Test Event')
+        new_event.settings.clear()
+        new_event.settings.add(new_setting)
+        new_event.save()
+
+        os.environ['JOB_SETTING_NAME'] = 'test2_job_setting.setting'
+        os.environ['JOB_OUT_PATH'] = os.path.join(
+            os.path.dirname(__file__), 'fixtures', 'fake_encoded_file2.mov')
+
+        new_dup_job = utils.create_job()
+        new_setting = new_dup_job.setting
+        new_event, created = Event.objects.get_or_create(name='Test2 Event')
+        new_event.settings.clear()
+        new_event.settings.add(new_setting)
+        new_event.save()
+
+        def signal_callback(sender, **kwargs):
+            self.assertTrue(isinstance(sender, Event))
+            #check the jobs kwarg is passed
+            self.assert_(kwargs.get('jobs', False))
+            #make sure it only sent one job
+            self.assertEquals(len(kwargs['jobs']),\
+                                sender.num_of_jobs or sender.settings.count())
+            signal_func_ran[0] = True
+
+        all_files_processed.connect(signal_callback)
+        mail.outbox = []
+
+        utils.check_event(new_job)
+        self.assertTrue(signal_func_ran[0], "Failed to encode first job, "
+                "probably because the number of jobs are more than the event")
+
+        signal_func_ran[0] = False
+        utils.check_event(new_dup_job)
+        self.assertTrue(signal_func_ran[0], "Failed to fire the second event")
+
+        self.assertEquals(len(mail.outbox), 2)
+        mail.outbox = []
+
+        signal_func_ran[0] = False
+
     def test_resubmission(self):
         new_job = utils.create_job()
         url = new_job.get_absolute_url()