diff --git a/pykolab/itip/__init__.py b/pykolab/itip/__init__.py --- a/pykolab/itip/__init__.py +++ b/pykolab/itip/__init__.py @@ -172,9 +172,14 @@ _iv = itip_event['xml'] _ii = 0 - while not conflict and _is is not None: + # T1988: For performance reasons we add "and _is < _ee" here + while not conflict and _is is not None and _is < _ee: # log.debug("* Comparing event dates at %s/%s with %s/%s" % (_es, _ee, _is, _ie), level=9) conflict = not _is_transparent(_ev) and not _is_transparent(_iv) and check_date_conflict(_es, _ee, _is, _ie) + # T1988: For performance reasons we modify recurrence iteration + if _is < _es: + _is = _is.replace(_es.year, _es.month, _es.day, 0, 0) + _is = to_dt(itip_event['xml'].get_next_occurence(_is)) if itip_event['xml'].is_recurring() else None _ie = to_dt(itip_event['xml'].get_occurence_end_date(_is)) diff --git a/tests/unit/test-011-itip.py b/tests/unit/test-011-itip.py --- a/tests/unit/test-011-itip.py +++ b/tests/unit/test-011-itip.py @@ -521,6 +521,22 @@ self.assertFalse(itip.check_event_conflict(event, itip_event), "Conflicting dates (exception)") + def test_002_check_event_conflict_forever_recurring(self): + # This test is here to make sure performance issue is fixed (T1988) + # make the event recurring forever + itip_recurring_forever = itip_recurring.replace("RRULE:FREQ=DAILY;INTERVAL=1;COUNT=5", "RRULE:FREQ=WEEKLY;BYDAY=MO") + itip_event = itip.events_from_message(message_from_string(itip_recurring_forever))[0] + + rrule = kolabformat.RecurrenceRule() + rrule.setFrequency(kolabformat.RecurrenceRule.Weekly) + + event = Event() + event.set_recurrence(rrule) + event.set_start(datetime.datetime(2012, 6, 29, 9, 30, 0, tzinfo=pytz.utc)) + event.set_end(datetime.datetime(2012, 6, 29, 10, 30, 0, tzinfo=pytz.utc)) + + self.assertFalse(itip.check_event_conflict(event, itip_event), "No conflict") + def test_003_send_reply(self): itip_events = itip.events_from_message(message_from_string(itip_non_multipart)) itip.send_reply("resource-collection-car@example.org", itip_events, "SUMMARY=%(summary)s; STATUS=%(status)s; NAME=%(name)s;")