Repository navigation
fix: conformance on Ox, Zimbra, SOGo, CCS and Bedework - #53
Merged
Merged
Conversation
SOGo adds RSVP=TRUE and PARTSTAT to an ATTENDEE that had none, Ox adds EMAIL=, and Ox adds the organizer to a meeting's attendees, as an RFC 6638 scheduling server does. verify and the conformance suite counted that as a change, though nothing the client sent is lost. A stored line now matches a sent one when it has the same value, every sent parameter, and added only parameters that say nothing about the value: X- ones, and CN, EMAIL, RSVP and SCHEDULE-* on an attendee or organizer. A parameter dropped or changed, one added with a meaning (a TZID, PARTSTAT=DECLINED, RELTYPE), or a line more or less, still is a difference. The one line more allowed is an attendee that is the stored organizer; each attendee sent must still be there. The property round trip in the conformance suite compares as verify does, instead of line by line. Prompt: ... and continue working on getting all the conformance tests passing Followup-Prompt: I think ... LOSSY is when information is lost, not when information is added [answer to: should verification tolerate parameters a server adds, or should attendees count as LOSSY there?] Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Deleting an occurrence rewrites the object, and Ox then gives every component a new DTSTAMP and LAST-MODIFIED. Deleting a sibling read before that raised ConflictError, as if another client had edited it. The check now leaves out what verify already skips (DTSTAMP, SEQUENCE, LAST-MODIFIED, UID), so only a real edit is a conflict. Zimbra drops a task's DTSTART. differences() compares a single start, end or due time as an instant, and read it from the stored component without checking it was there, so verify=True raised KeyError instead of reporting the loss. Prompt: ... and continue working on getting all the conformance tests passing Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Zimbra and SOGo keep a TZID but store a floating time in UTC. timezones covers both kinds of time, so no level said that, and the floating corpus event failed on these servers. The new capability says what becomes of a floating time only; the CalDAV backend declares it lossy where caldav's save-load.event.floating hint is unsupported, and unknown on a task list: the hint is probed on events, and SOGo keeps a task's floating times. Where timezones is lowered it converts floating times as before. Prompt: ... and continue working on getting all the conformance tests passing Followup-Prompt: [Floating times should get a new capability timezones.floating] and a tester probe and new caldav hint Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Zimbra drops a task's DTSTART where it has no DUE, and Ox drops its COMPLETED where it has no STATUS; nothing said so, and the writes lost them silently. A LOSSY capability may now name what a property requires, and the loss planner reports the property as lost where none of those is there. The CalDAV backend declares task.start that way where caldav's new hint save-load.todo.dtstart-without-due is unsupported, and task.completed where save-load.todo.completed-without-status is; both come from one table. Prompt: ... and continue working on getting all the conformance tests passing Followup-Prompt: [Floating times should get a new capability timezones.floating] and a tester probe and new caldav hint Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Bedework 5 makes an object readable, and findable, a few seconds after the PUT is answered. wait_out_search_cache becomes wait_for_server: a GET or multiget of a recently written object waits out caldav's synchronous-write delay, and searches wait the same delay where the server has no search-cache delay of its own. Only reads of fresh objects wait, not every write as in caldav's own tests. Prompt: [get the conformance tests to pass on Bedework 5] Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Ox keeps a task's VALARM but makes its trigger absolute and replaces its description, as caldav's new save-load.todo.alarm hint says. On a task list where the hint is broken, alarms are LOSSY: the loss policy hears of it, the alarm is sent as it is, and verify lets a rewritten VALARM pass, though not a dropped one. Where the hint is unsupported they are dropped. A calendar holding events too keeps FULL. The loss gets a note saying how the server changes the value, as the backend cannot tell what it will store; stored is then the value as sent, and the warn policy shows the note. Prompt: [we probably need] another probe in the caldav-server-tester library on whether task lists accept alarms Followup-Prompt: save-load.todo.alarm is fine, and it's possible to use the behaviour or extra_keys to elaborate why it's broken. Followup-Prompt: [Loss should get a separate note field] Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
CCS stores an event with TZID=Europe/Oslo but drops its VTIMEZONE, which RFC 5545 section 3.2.19 requires, so the conformance round trip of an event series in a time zone failed there. A CalDAV read now adds the missing VTIMEZONE from zoneinfo; the server's bytes stay in .wire as received. Prompt: [pick from the task list: "calendaring: remaining conformance failures on Ox, Zimbra and others"] Followup-Prompt: ... First priority is to get the conformance tests passing for all the caldav servers available ... Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Bedework (3 and 5) refuses a new object under a taken name with 500, not 412, so caldav's hint for it becomes save.if-none-match "ungraceful". That maps to identity.client-native-id "emulated", as for SOGo: caldav GETs the name before the PUT. The comment said only "overwrites". Prompt: [pick from the task list: "calendaring: remaining conformance failures on Ox, Zimbra and others"] Followup-Prompt: ... First priority is to get the conformance tests passing for all the caldav servers available ... Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Zimbra 8.8 and 10.1 drop every RDATE, timed or all-day, and keep an RRULE, so the all-day corpus event with an RDATE failed verify there. recurrence covers RRULE, RDATE and EXDATE alike; declaring it lossy would have said the RRULE is lost too. The new capability says what becomes of an RDATE alone: where it is unsupported the loss planner drops an event's RDATE, and the overrides of the occurrences only it gives, and reports them. The CalDAV backend reads caldav's new save-load.event.recurrences.rdate hint, and declares it unknown on a task list, as the hint is probed on events. Prompt: [about Zimbra 10.1 dropping RDATE only inside the suite's run:] Keep digging. Followup-Prompt: new feature [answer to: should calendaring get a new recurrence.rdate feature, or declare all of RECURRENCE lossy on Zimbra?] Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Loss.sent and Loss.stored are typed as any value, and mypy refused _alarms() taking only a string. It now takes what a Loss holds. Prompt: [fix issues found during the review process] Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
The VTIMEZONE test read .end off an icalendar.Component, which mypy
rejects in CI ("Component" has no attribute "end"). An isinstance
assert on icalendar.Todo narrows the type.
Prompt: Look through the last two PRs. Pipeline seems to have failed
Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
Stalwart cuts a long listing at its WebDav.maxResults with a 507, and caldav keeps none of it, so a listing there failed as a bare BackendError. listing.complete is now unsupported where caldav's search, propfind or multiget limit hint says so, and the 507 raises ListingLimitError, which the conformance test accepts only there. Prompt: Continue working on getting those [calendaring] conformance tests passing. Prompts [Declare the limit as a problem and let it fail] as for now, and it should be raised with the Stalwart. (...) Assisted-By: Claude Opus 5.5 <noreply@anthropic.com> Reviewed-by: Tobias Brox <tobias@redpill-linpro.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Disclaimer: AI-generated code and text below the line, generated by Claude Opus 5.5
Work towards a conformance suite that passes on every CalDAV test server.
verifyand the suite now tell what a server adds harmlessly (parameters that say nothing about the value, the organizer as an attendee, re-stamped occurrences) from real changes (a dropped start, a parameter added with a meaning such as a TZID orPARTSTAT=DECLINED). The CalDAV backend declares more of what servers lose, from caldav's hints: floating times stored in UTC (timezones.floating), a task start Zimbra keeps only with a due and a COMPLETED Ox keeps only with a STATUS (a capability may now name what a property requires), task alarms Ox rewrites (lossy, with aLoss.notesaying how), and a newrecurrence.rdatecapability for the RDATE Zimbra drops while keeping the RRULE. A VTIMEZONE the server dropped (CCS) is put back on read, Bedework's 500 for a taken name maps to an emulated native id, and the test harness waits for Bedework 5 to settle after writes.New capability
listing.completeand errorListingLimitError: Stalwart cuts a long listing at itsWebDav.maxResultswith a 507, and caldav keeps none of it. Where caldav's limit hints say so, the backend declares the limit, and a 507 in a listing raisesListingLimitErrorinstead of a bareBackendError.With the caldav hints this needs (python-caldav/caldav#855 and python-caldav/caldav#856, merged; python-caldav/caldav#861 and python-caldav/caldav#862 for Robur; the task-alarm hint still to come), the suite passes on Zimbra 8.8, Ox, Cyrus, DAViCal, Davis, Baikal, Nextcloud, Radicale, Xandikos, CCS, Bedework 3 and Stalwart. Still failing: Bedework 5 stores every ATTENDEE twice; robur's own server errors (500 on PUT, dropped connections); ecloud's calendar-creation rate limit. CI runs released caldav, where the tests for the new hints are skipped.