Ejemplo n.º 1
0
 def _runAllJobs(self):
     """
     Run all outstanding jobs.
     """
     # Run jobs
     jobs = yield JobItem.all(self.transactionUnderTest())
     while jobs:
         yield jobs[0].run()
         yield self.commit()
         jobs = yield JobItem.all(self.transactionUnderTest())
     yield self.commit()
Ejemplo n.º 2
0
    def test_cascade_delete_cleanup(self):
        """
        Test that when work associated with L{txdav.caldav.datastore.scheduling.work.ScheduleWork}
        is removed with the L{ScheduleWork} item being removed, the associated L{JobItem} runs and
        removes itself and the L{ScheduleWork}.
        """

        ScheduleWorkMixin._queued = 0
        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerWork.schedule(
            txn,
            "12345-67890",
            "create",
            home,
            None,
            None,
            self.calendar_new,
            "urn:uuid:user01",
            2,
            True,
        )
        yield self.commit()
        self.assertEqual(ScheduleWorkMixin._queued, 1)

        jobs = yield JobItem.all(self.transactionUnderTest())
        work = yield jobs[0].workItem()
        yield WorkItem.delete(work)
        yield self.commit()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 1)
        self.assertEqual(baseWork[0].jobID, jobs[0].jobID)

        work = yield jobs[0].workItem()
        self.assertTrue(work is None)
        yield self.commit()

        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor,
                                60)

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        work = yield ScheduleOrganizerWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 0)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 0)
Ejemplo n.º 3
0
    def test_cascade_delete_cleanup(self):
        """
        Test that when work associated with L{txdav.caldav.datastore.scheduling.work.ScheduleWork}
        is removed with the L{ScheduleWork} item being removed, the associated L{JobItem} runs and
        removes itself and the L{ScheduleWork}.
        """

        ScheduleWorkMixin._queued = 0
        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerWork.schedule(
            txn,
            "12345-67890",
            "create",
            home,
            None,
            None,
            self.calendar_new,
            "urn:uuid:user01",
            2,
            True,
        )
        yield self.commit()
        self.assertEqual(ScheduleWorkMixin._queued, 1)

        jobs = yield JobItem.all(self.transactionUnderTest())
        work = yield jobs[0].workItem()
        yield WorkItem.delete(work)
        yield self.commit()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 1)
        self.assertEqual(baseWork[0].jobID, jobs[0].jobID)

        work = yield jobs[0].workItem()
        self.assertTrue(work is None)
        yield self.commit()

        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        work = yield ScheduleOrganizerWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 0)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 0)
Ejemplo n.º 4
0
    def test_create(self):
        """
        Test that jobs associated with L{txdav.caldav.datastore.scheduling.work.ScheduleOrganizerSendWork}
        can be created and correctly removed.
        """

        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerSendWork.schedule(
            txn,
            "create",
            home,
            None,
            "urn:x-uid:user01",
            "urn:x-uid:user02",
            self.itip_new,
            True,
            1000,
        )

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)

        work = yield jobs[0].workItem()
        yield work.doWork()

        home2 = yield self.calendarUnderTest(home="user02", name="calendar")
        cobjs = yield home2.calendarObjects()
        self.assertEqual(len(cobjs), 1)
        # cal2 = yield cobjs[0].component()

        yield work.delete()
        yield jobs[0].delete()
        yield self.commit()
Ejemplo n.º 5
0
        def stopIt():
            txn = store.newTransaction()
            jobs = yield JobItem.all(txn)
            yield txn.commit()

            if enableJobProcessing:
                yield pool.stopService()

            # active transactions should have been shut down.
            wasBusy = len(cp._busy)
            busyText = repr(cp._busy)
            result = yield cp.stopService()

            if deriveValue(testCase, _SPECIAL_TXN_CLEAN, lambda tc: False):
                if wasBusy:
                    testCase.fail("Outstanding Transactions: " + busyText)
                returnValue(result)

            if len(jobs):
                testCase.fail("Jobs left in job queue {}: {}".format(
                    testCase,
                    ",".join([job.workType for job in jobs])
                ))

            returnValue(result)
Ejemplo n.º 6
0
    def test_create(self):
        """
        Test that jobs associated with L{txdav.caldav.datastore.scheduling.work.ScheduleOrganizerSendWork}
        can be created and correctly removed.
        """

        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerSendWork.schedule(
            txn,
            "create",
            home,
            None,
            "urn:x-uid:user01",
            "urn:x-uid:user02",
            self.itip_new,
            True,
            1000,
        )

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)

        work = yield jobs[0].workItem()
        yield work.doWork()

        home2 = yield self.calendarUnderTest(home="user02", name="calendar")
        cobjs = yield home2.calendarObjects()
        self.assertEqual(len(cobjs), 1)
        #cal2 = yield cobjs[0].component()

        yield work.delete()
        yield jobs[0].delete()
        yield self.commit()
Ejemplo n.º 7
0
 def _runOneJob(self):
     """
     Run the first outstanding jobs.
     """
     # Run jobs
     jobs = yield JobItem.all(self.transactionUnderTest())
     for job in jobs:
         yield job.run()
         break
     yield self.commit()
Ejemplo n.º 8
0
    def test_create(self):
        """
        Test that jobs associated with L{txdav.caldav.datastore.scheduling.work.ScheduleOrganizerWork}
        can be created and correctly removed.
        """

        ScheduleWorkMixin._queued = 0
        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerWork.schedule(
            txn,
            "12345-67890",
            "create",
            home,
            None,
            None,
            self.calendar_new,
            "urn:uuid:user01",
            2,
            True,
        )
        yield self.commit()
        self.assertEqual(ScheduleWorkMixin._queued, 1)

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)

        work = yield jobs[0].workItem()
        self.assertTrue(isinstance(work, ScheduleOrganizerWork))
        self.assertEqual(work.icalendarUid, "12345-67890")
        self.assertEqual(scheduleActionFromSQL[work.scheduleAction], "create")

        yield work.delete()
        yield jobs[0].delete()
        yield self.commit()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        work = yield ScheduleOrganizerWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 0)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 0)
Ejemplo n.º 9
0
    def test_create(self):
        """
        Test that jobs associated with L{txdav.caldav.datastore.scheduling.work.ScheduleOrganizerWork}
        can be created and correctly removed.
        """

        ScheduleWorkMixin._queued = 0
        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerWork.schedule(
            txn,
            "12345-67890",
            "create",
            home,
            None,
            None,
            self.calendar_new,
            "urn:uuid:user01",
            2,
            True,
        )
        yield self.commit()
        self.assertEqual(ScheduleWorkMixin._queued, 1)

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)

        work = yield jobs[0].workItem()
        self.assertTrue(isinstance(work, ScheduleOrganizerWork))
        self.assertEqual(work.icalendarUid, "12345-67890")
        self.assertEqual(scheduleActionFromSQL[work.scheduleAction], "create")

        yield work.delete()
        yield jobs[0].delete()
        yield self.commit()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        work = yield ScheduleOrganizerWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 0)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 0)
Ejemplo n.º 10
0
        def stopIt():
            txn = store.newTransaction()
            jobs = yield JobItem.all(txn)
            yield txn.commit()
            if len(jobs):
                print("Jobs left in job queue {}: {}".format(
                    testCase,
                    ",".join([job.workType for job in jobs])
                ))

            if enableJobProcessing:
                yield pool.stopService()

            # active transactions should have been shut down.
            wasBusy = len(cp._busy)
            busyText = repr(cp._busy)
            result = yield cp.stopService()
            if deriveValue(testCase, _SPECIAL_TXN_CLEAN, lambda tc: False):
                if wasBusy:
                    testCase.fail("Outstanding Transactions: " + busyText)
                returnValue(result)
            returnValue(result)
Ejemplo n.º 11
0
    def test_replyBeforeOrganizerConsequentialChange(self):
        """
        Test that the organizer and attendee see the attendee's partstat change when the organizer makes
        a consequential change whilst the attendee reply is in progress.
        """

        organizer1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02
END:VEVENT
END:VCALENDAR
""")

        organizer2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080602T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02
SUMMARY:Test
END:VEVENT
END:VCALENDAR
""")

        organizer3 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080602T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2;X-CALENDARSERVER-RESET-PARTSTAT=1:urn:x-uid:user02
SEQUENCE:1
SUMMARY:Test
END:VEVENT
END:VCALENDAR
""")

        attendee1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        attendee2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user02
END:VEVENT
END:VCALENDAR
""")

        attendee3 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080602T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected];SCHEDULE-STATUS=1.2:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
SEQUENCE:1
SUMMARY:Test
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")


        yield self.createOrganizerEvent("user01", organizer1)
        attendee = yield self.getAttendeeEvent("user02")
        self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1))

        yield self.setOrganizerEvent("user01", organizer2, run_jobs=False)
        yield self._runOneJob()
        yield self.setAttendeeEvent("user02", attendee2, run_jobs=False)

        yield self._runAllJobs()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        yield self.commit()

        organizer = yield self.getOrganizerEvent("user01")
        self.assertEqual(normalize_iCalStr(organizer), normalize_iCalStr(organizer3), msg=diff_iCalStrs(organizer3, organizer))
        attendee = yield self.getAttendeeEvent("user02")
        self.assertEqual(normalize_iCalStr(attendee), normalize_iCalStr(attendee3), msg=diff_iCalStrs(attendee3, attendee))
Ejemplo n.º 12
0
    def test_replyBeforeOrganizerEXDATE(self):
        """
        Test that a reply is sent if an attendee changes an event, but the organizer exdate's
        the instance before the reply work is processed.
        """

        organizer1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02
RRULE:FREQ=DAILY
END:VEVENT
END:VCALENDAR
""")

        attendee1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
RRULE:FREQ=DAILY
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        organizer2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02
EXDATE:20080602T130000Z
RRULE:FREQ=DAILY
SUMMARY:Test
END:VEVENT
END:VCALENDAR
""")

        attendee2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
RRULE:FREQ=DAILY
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
UID:12345-67890
RECURRENCE-ID:20080602T130000Z
DTSTAMP:20080601T130000Z
DTSTART:20080602T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED:urn:x-uid:user02
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        attendee3 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
EXDATE:20080602T130000Z
RRULE:FREQ=DAILY
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        yield self.createOrganizerEvent("user01", organizer1)
        attendee = yield self.getAttendeeEvent("user02")
        self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1))

        yield self.setOrganizerEvent("user01", organizer2, run_jobs=False)
        yield self._runOneJob()
        yield self.setAttendeeEvent("user02", attendee2, run_jobs=False)
        yield self.setAttendeeEvent("user02", attendee3, run_jobs=False)

        yield self._runAllJobs()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        yield self.commit()
Ejemplo n.º 13
0
    def test_replyBeforeResourceDelete(self):
        """
        Test that a reply is sent if an attendee changes an event, then immediately deletes it.
        """

        organizer1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION:urn:x-uid:user02
END:VEVENT
END:VCALENDAR
""")

        attendee1 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=NEEDS-ACTION;RSVP=TRUE:urn:x-uid:user02
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        organizer2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0:urn:x-uid:user02
END:VEVENT
END:VCALENDAR
""")

        attendee2 = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20080601T130000Z
DTSTART:20080601T130000Z
DURATION:PT1H
ORGANIZER;CN=User 01;[email protected]:urn:x-uid:user01
ATTENDEE;CN=User 01;[email protected];PARTSTAT=ACCEPTED:urn:x-uid:user01
ATTENDEE;CN=User 02;[email protected];PARTSTAT=DECLINED:urn:x-uid:user02
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
""")

        yield self.createOrganizerEvent("user01", organizer1)
        attendee = yield self.getAttendeeEvent("user02")
        self.assertEqual(attendee, attendee1, msg=diff_iCalStrs(attendee, attendee1))

        yield self.setAttendeeEvent("user02", attendee2, run_jobs=False)
        calobj = yield self.getAttendeeResource("user02")
        yield calobj.remove()
        yield self.commit()

        yield self._runAllJobs()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        yield self.commit()

        organizer = yield self.getOrganizerEvent("user01")
        self.assertEqual(organizer, organizer2, msg=diff_iCalStrs(organizer, organizer2))
Ejemplo n.º 14
0
    def test_upgrade_SCHEDULE_REPLY(self):

        cal1 = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:1234-5678
DTSTART:20071114T010000Z
DURATION:PT1H
DTSTAMP:20071114T000000Z
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
ORGANIZER:mailto:[email protected]
SUMMARY:Test
END:VEVENT
END:VCALENDAR
"""

        # Load old schema and populate with data
        schema = yield self._loadOldSchema(self.upgradePath.child("v49.sql"))

        txn = self.store.newTransaction("loadData")
        yield Insert({
            schema.CALENDAR_HOME.RESOURCE_ID: 1,
            schema.CALENDAR_HOME.OWNER_UID: "abcdefg",
        }).on(txn)
        yield Insert({
            schema.CALENDAR.RESOURCE_ID: 2,
        }).on(txn)
        yield Insert({
            schema.CALENDAR_OBJECT.RESOURCE_ID: 3,
            schema.CALENDAR_OBJECT.CALENDAR_RESOURCE_ID: 2,
            schema.CALENDAR_OBJECT.RESOURCE_NAME: "1.ics",
            schema.CALENDAR_OBJECT.ICALENDAR_TEXT: cal1,
            schema.CALENDAR_OBJECT.ICALENDAR_UID: "1234-5678",
            schema.CALENDAR_OBJECT.ICALENDAR_TYPE: "VEVENT",
            schema.CALENDAR_OBJECT.MD5: "md5-1234567890",
        }).on(txn)
        yield Insert({
            schema.JOB.JOB_ID: 1,
            schema.JOB.WORK_TYPE: "SCHEDULE_REPLY_WORK",
            schema.JOB.NOT_BEFORE: datetime.utcnow(),
        }).on(txn)
        yield Insert({
            schema.SCHEDULE_WORK.WORK_ID: 1,
            schema.SCHEDULE_WORK.JOB_ID: 1,
            schema.SCHEDULE_WORK.ICALENDAR_UID: "1234-5678",
            schema.SCHEDULE_WORK.WORK_TYPE: "SCHEDULE_REPLY_WORK",
        }).on(txn)
        yield Insert({
            schema.SCHEDULE_REPLY_WORK.WORK_ID: 1,
            schema.SCHEDULE_REPLY_WORK.HOME_RESOURCE_ID: 1,
            schema.SCHEDULE_REPLY_WORK.RESOURCE_ID: 3,
            schema.SCHEDULE_REPLY_WORK.CHANGED_RIDS: None,
        }).on(txn)
        yield txn.commit()

        # Try to upgrade and verify new version afterwards
        upgrader = UpgradeDatabaseSchemaStep(self.store)
        yield upgrader.databaseUpgrade()

        new_version = yield self._loadVersion()
        self.assertEqual(new_version, self.currentVersion)

        txn = self.store.newTransaction("loadData")
        jobs = yield Select(From=schema.JOB, ).on(txn)
        schedules = yield Select(From=schema.SCHEDULE_WORK, ).on(txn)
        replies = yield Select(From=schema.SCHEDULE_REPLY_WORK, ).on(txn)

        self.assertEqual(len(jobs), 1)
        self.assertEqual(len(schedules), 1)
        self.assertEqual(len(replies), 1)

        self.assertEqual(replies[0], [
            1,
            1,
            3,
            None,
        ])

        jobs = yield JobItem.all(txn)
        self.assertEqual(len(jobs), 1)
        work = yield jobs[0].workItem()
        self.assertTrue(isinstance(work, ScheduleReplyWork))

        workers = yield ScheduleWork.all(txn)
        self.assertEqual(len(workers), 1)
        self.assertEqual(workers[0].workType, "SCHEDULE_REPLY_WORK")

        yield txn.commit()
Ejemplo n.º 15
0
    def poll(self):
        if self._polling:
            return

        self._polling = True

        txn = self._store.newTransaction()
        try:

            # Look up all of the jobs

            events = []

            jobsByTypeName = {}

            for job in (yield JobItem.all(txn)):
                jobsByTypeName.setdefault(job.workType, []).append(job)

            totalsByTypeName = {}

            for workType in JobItem.workTypes():
                typeName = workType.table.model.name
                jobs = jobsByTypeName.get(typeName, [])
                totalsByTypeName[typeName] = len(jobs)

                jobDicts = []

                for job in jobs:
                    def formatTime(datetime):
                        if datetime is None:
                            return None
                        else:
                            # FIXME: Use HTTP time format
                            return datetime.ctime()

                    jobDict = dict(
                        job_jobID=job.jobID,
                        job_priority=job.priority,
                        job_weight=job.weight,
                        job_notBefore=formatTime(job.notBefore),
                    )

                    work = yield job.workItem()

                    attrs = ("workID", "group")

                    if workType == PushNotificationWork:
                        attrs += ("pushID", "priority")
                    elif workType == ScheduleOrganizerWork:
                        attrs += ("icalendarUid", "attendeeCount")
                    elif workType == ScheduleRefreshWork:
                        attrs += ("icalendarUid", "attendeeCount")
                    elif workType == ScheduleReplyWork:
                        attrs += ("icalendarUid",)
                    elif workType == ScheduleAutoReplyWork:
                        attrs += ("icalendarUid",)
                    elif workType == GroupCacherPollingWork:
                        attrs += ()
                    elif workType == IMIPPollingWork:
                        attrs += ()
                    elif workType == IMIPReplyWork:
                        attrs += ("organizer", "attendee")
                    else:
                        attrs = ()

                    if attrs:
                        if work is None:
                            self.log.error(
                                "workItem() returned None for job: {job}",
                                job=job
                            )
                            # jobDict.update((attr, None) for attr in attrs)
                            for attr in attrs:
                                jobDict["work_{}".format(attr)] = None
                        else:
                            # jobDict.update(
                            #     ("work_{}".format(attr), getattr(work, attr))
                            #     for attr in attrs
                            # )
                            for attr in attrs:
                                jobDict["work_{}".format(attr)] = (
                                    getattr(work, attr)
                                )

                    jobDicts.append(jobDict)

                if jobDicts:
                    events.append(dict(
                        eventClass=typeName,
                        eventID=time(),
                        eventText=asJSON(jobDicts),
                    ))

            events.append(dict(
                eventClass=u"work-total",
                eventID=time(),
                eventText=asJSON(totalsByTypeName),
                eventRetry=(self._pollInterval),
            ))

            # Send data

            self.addEvents(events)

        except:
            self._polling = False
            yield txn.abort()
            raise
        else:
            yield txn.commit()

        # Schedule the next poll

        if not hasattr(self, "_clock"):
            from twisted.internet import reactor
            self._clock = reactor

        self._clock.callLater(self._pollInterval / 1000, self.poll)
Ejemplo n.º 16
0
    def poll(self):
        if self._polling:
            return

        self._polling = True

        txn = self._store.newTransaction()
        try:

            # Look up all of the jobs

            events = []

            jobsByTypeName = {}

            for job in (yield JobItem.all(txn)):
                jobsByTypeName.setdefault(job.workType, []).append(job)

            totalsByTypeName = {}

            for workType in JobItem.workTypes():
                typeName = workType.table.model.name
                jobs = jobsByTypeName.get(typeName, [])
                totalsByTypeName[typeName] = len(jobs)

                jobDicts = []

                for job in jobs:

                    def formatTime(datetime):
                        if datetime is None:
                            return None
                        else:
                            # FIXME: Use HTTP time format
                            return datetime.ctime()

                    jobDict = dict(
                        job_jobID=job.jobID,
                        job_priority=job.priority,
                        job_weight=job.weight,
                        job_notBefore=formatTime(job.notBefore),
                    )

                    work = yield job.workItem()

                    attrs = ("workID", "group")

                    if workType == PushNotificationWork:
                        attrs += ("pushID", "priority")
                    elif workType == ScheduleOrganizerWork:
                        attrs += ("icalendarUid", "attendeeCount")
                    elif workType == ScheduleRefreshWork:
                        attrs += ("icalendarUid", "attendeeCount")
                    elif workType == ScheduleReplyWork:
                        attrs += ("icalendarUid", )
                    elif workType == ScheduleAutoReplyWork:
                        attrs += ("icalendarUid", )
                    elif workType == GroupCacherPollingWork:
                        attrs += ()
                    elif workType == IMIPPollingWork:
                        attrs += ()
                    elif workType == IMIPReplyWork:
                        attrs += ("organizer", "attendee")
                    else:
                        attrs = ()

                    if attrs:
                        if work is None:
                            self.log.error(
                                "workItem() returned None for job: {job}",
                                job=job)
                            # jobDict.update((attr, None) for attr in attrs)
                            for attr in attrs:
                                jobDict["work_{}".format(attr)] = None
                        else:
                            # jobDict.update(
                            #     ("work_{}".format(attr), getattr(work, attr))
                            #     for attr in attrs
                            # )
                            for attr in attrs:
                                jobDict["work_{}".format(attr)] = (getattr(
                                    work, attr))

                    jobDicts.append(jobDict)

                if jobDicts:
                    events.append(
                        dict(
                            eventClass=typeName,
                            eventID=time(),
                            eventText=asJSON(jobDicts),
                        ))

            events.append(
                dict(
                    eventClass=u"work-total",
                    eventID=time(),
                    eventText=asJSON(totalsByTypeName),
                    eventRetry=(self._pollInterval),
                ))

            # Send data

            self.addEvents(events)

        except:
            self._polling = False
            yield txn.abort()
            raise
        else:
            yield txn.commit()

        # Schedule the next poll

        if not hasattr(self, "_clock"):
            from twisted.internet import reactor
            self._clock = reactor

        self._clock.callLater(self._pollInterval / 1000, self.poll)
    def test_connectionRefusedForAttendee(self):
        data_organizer = """BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:uid_data
DTSTART:{now1:04d}0102T160000Z
DURATION:PT1H
CREATED:20060102T190000Z
DTSTAMP:20051222T210507Z
SUMMARY:data01_2
ORGANIZER:mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n").format(**self.now)

        data_attendee = """BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:uid_data
DTSTART:{now1:04d}0102T160000Z
DURATION:PT1H
CREATED:20060102T190000Z
DTSTAMP:20051222T210507Z
SUMMARY:data01_2
ORGANIZER:mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE;PARTSTAT=DECLINED:mailto:[email protected]
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n").format(**self.now)

        # Organizer schedules
        home = yield self.homeUnderTest(txn=self.theTransactionUnderTest(0), name="user01", create=True)
        calendar = yield home.childWithName("calendar")
        yield calendar.createCalendarObjectWithName("1.ics", Component.fromString(data_organizer))
        yield self.commitTransaction(0)

        yield self.waitAllEmpty()

        # Data for user02
        home = yield self.homeUnderTest(txn=self.theTransactionUnderTest(0), name="user02", create=True)
        calendar = yield home.childWithName("calendar")
        cobjs = yield calendar.calendarObjects()
        self.assertEqual(len(cobjs), 1)
        self.assertEqual(cobjs[0].uid(), "uid_data")
        yield self.commitTransaction(0)

        # Data for puser02
        home = yield self.homeUnderTest(txn=self.theTransactionUnderTest(1), name="puser02", create=True)
        calendar = yield home.childWithName("calendar")
        cobjs = yield calendar.calendarObjects()
        self.assertEqual(len(cobjs), 1)
        self.assertEqual(cobjs[0].uid(), "uid_data")
        yield self.commitTransaction(1)

        # Stop cross-pod connection from working
        self.refuseConnection = True

        # Attendee changes
        home = yield self.homeUnderTest(txn=self.theTransactionUnderTest(1), name="puser02", create=True)
        calendar = yield home.childWithName("calendar")
        cobjs = yield calendar.calendarObjects()
        yield cobjs[0].setComponent(Component.fromString(data_attendee))
        yield self.commitTransaction(1)

        while True:
            jobs = yield JobItem.all(self.theTransactionUnderTest(1))
            yield self.commitTransaction(1)
            if len(jobs) == 1 and jobs[0].failed > 0:
                break

        # Organizer data unchanged
        cobj = yield self.calendarObjectUnderTest(txn=self.theTransactionUnderTest(0), home="user01", calendar_name="calendar", name="1.ics")
        comp = yield cobj.componentForUser()
        self.assertTrue("DECLINED" not in str(comp))
        yield self.commitTransaction(0)

        # Now allow cross-pod to work
        self.refuseConnection = False

        yield self.waitAllEmpty()

        # Organizer data changed
        cobj = yield self.calendarObjectUnderTest(txn=self.theTransactionUnderTest(0), home="user01", calendar_name="calendar", name="1.ics")
        comp = yield cobj.componentForUser()
        self.assertTrue("DECLINED" in str(comp))
        yield self.commitTransaction(0)