Skip to content

Commit 7c52767

Browse files
authored
Bugfixes, workarounds and Bedework test server
I introduced Bedework test server, and had another multi-day-session of "banging on things until all tests pass" - and while doing so, tons of different commits on different things gets added to the same pull request. I've asked Claude to rebase it into some few well-organized commits, but i'm not much happy with the result, so I will again make a jumbo-commit. My own non-AI-assisted summary of the changes introduced in this pull request looks like this: Test framework: * Changes in the github workflow and test suite to run tests towards bedework. The bedework docker container is quite straigth forward, comes up with some default test user and password, no extra dependencies. But it's very old, not maintained and quite buggy. * Lots of tweaks in the test code to get it pass on Bedework and all the other servers * Fix for SOGo - tests didn't want to run with github runners. Code logic: * Due to the previous changeset with transparent workarounds for servers not supporting sync-tokens, my compatibility check script started reporting that all servers supported sync-tokens. To revert to the old behaviour, I needed to add a disable_fallback parameer to the objects_by_sync_token method. * Continued massaging and bugfixing on the compatibility_hints.py. - Added synology compatibility matrix - Added bedework compatibility matrix - Lots of "unsupported" stuff has been reclassified into "ungraceful". - Some more features added to the definitions - Bugfix in FeatureSet constructor. * Downgraded an annoying "CRITICAL" to "INFO" (some servers sends unexpected content-type on errors or empty responses) * Workaround to handle Bedework in search - Bedework does not handle the component filter right - if asking for events, it will send everything, and when askin g for todos it will send ... nothing! There is now a workaround in the search algorithm. * If the server can't do text-searches, then we should use client-side filtering of completed tasks. * Bugfix to the auto-discover URL code - it did not work very well together with the "read the URL from the compatibility_hints.py" logic The AI-generated summary of this jumbo-commit will be added as a comment to the github pull request at #584
1 parent 2ce2278 commit 7c52767

File tree

14 files changed

+487
-130
lines changed

14 files changed

+487
-130
lines changed

.github/workflows/tests.yaml

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ jobs:
6666
--health-timeout 5s
6767
--health-retries 20
6868
--health-start-period 10s
69+
--network-alias db
6970
sogo:
7071
image: japoch/sogo:latest
7172
ports:
@@ -75,6 +76,16 @@ jobs:
7576
sogo_pass: testpass
7677
sogo_name: Test User
7778
sogo_fqhn: example.com
79+
bedework:
80+
image: ioggstream/bedework:latest
81+
ports:
82+
- 8804:8080
83+
options: >-
84+
--health-cmd "curl -f http://localhost:8080/bedework/ || exit 1"
85+
--health-interval 10s
86+
--health-timeout 5s
87+
--health-retries 15
88+
--health-start-period 120s
7889
steps:
7990
- uses: actions/checkout@v4
8091
- uses: actions/setup-python@v5
@@ -209,26 +220,24 @@ jobs:
209220
run: |
210221
echo "Configuring SOGo..."
211222
212-
# Wait for SOGo container to start (it won't be healthy yet due to missing DB config)
223+
# Wait for database to be ready
224+
echo "Waiting for database..."
213225
sleep 5
214226
215-
# Get database container hostname
216-
DB_HOST=$(docker inspect ${{ job.services.sogo-db.id }} --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}')
217-
echo "Database host: $DB_HOST"
218-
219-
# Copy and modify configuration to use correct database hostname
220-
sed "s/@db:/@$DB_HOST:/g" tests/docker-test-servers/sogo/sogo.conf > /tmp/sogo.conf
221-
docker cp /tmp/sogo.conf ${{ job.services.sogo.id }}:/etc/sogo/sogo.conf
222-
docker cp tests/docker-test-servers/sogo/init-sogo-users.sql ${{ job.services.sogo-db.id }}:/tmp/init-sogo-users.sql
223-
224227
# Initialize database with test user
228+
docker cp tests/docker-test-servers/sogo/init-sogo-users.sql ${{ job.services.sogo-db.id }}:/tmp/init-sogo-users.sql
225229
docker exec -i ${{ job.services.sogo-db.id }} mariadb -usogo -psogo sogo < tests/docker-test-servers/sogo/init-sogo-users.sql
230+
echo "✓ Database initialized with test user"
231+
232+
# Copy SOGo configuration (database is now reachable via network alias 'db')
233+
docker cp tests/docker-test-servers/sogo/sogo.conf ${{ job.services.sogo.id }}:/etc/sogo/sogo.conf
234+
echo "✓ SOGo configuration copied"
226235
227236
# Restart SOGo to pick up configuration
228237
docker restart ${{ job.services.sogo.id }}
229238
230239
# Wait for SOGo to be ready
231-
echo "Waiting for SOGo..."
240+
echo "Waiting for SOGo to start..."
232241
if timeout 60 bash -c 'until curl -f http://localhost:8803/SOGo/ 2>/dev/null; do echo -n "."; sleep 2; done'; then
233242
echo ""
234243
echo "✓ SOGo is ready"
@@ -246,12 +255,34 @@ jobs:
246255
echo "✗ Error: SOGo CalDAV access failed"
247256
exit 1
248257
fi
258+
- name: Configure Bedework
259+
run: |
260+
echo "Waiting for Bedework..."
261+
# Bedework/JBoss takes longer to start up
262+
if timeout 180 bash -c 'until curl -f http://localhost:8804/bedework/ 2>/dev/null; do echo -n "."; sleep 5; done'; then
263+
echo ""
264+
echo "✓ Bedework web interface is ready"
265+
else
266+
echo ""
267+
echo "✗ Error: Bedework did not become ready within 180 seconds"
268+
exit 1
269+
fi
270+
271+
# Verify CalDAV access with default user (vbede:bedework)
272+
echo "Verifying CalDAV access..."
273+
if curl -s -X PROPFIND -H "Depth: 0" -u vbede:bedework http://localhost:8804/ucaldav/user/vbede/ 2>/dev/null | grep -qi "multistatus"; then
274+
echo "✓ Bedework CalDAV access verified"
275+
else
276+
echo "✗ Error: Bedework CalDAV access failed"
277+
exit 1
278+
fi
249279
- run: tox -e py
250280
env:
251281
NEXTCLOUD_URL: http://localhost:8801
252282
BAIKAL_URL: http://localhost:8800
253283
CYRUS_URL: http://localhost:8802
254284
SOGO_URL: http://localhost:8803
285+
BEDEWORK_URL: http://localhost:8804
255286
docs:
256287
runs-on: ubuntu-latest
257288
steps:

caldav/collection.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,10 @@ def _generate_fake_sync_token(self, objects: List["CalendarObjectResource"]) ->
11411141
return f"fake-{hash_value}"
11421142

11431143
def objects_by_sync_token(
1144-
self, sync_token: Optional[Any] = None, load_objects: bool = False
1144+
self,
1145+
sync_token: Optional[Any] = None,
1146+
load_objects: bool = False,
1147+
disable_fallback: bool = False,
11451148
) -> "SynchronizableCalendarObjectCollection":
11461149
"""objects_by_sync_token aka objects
11471150
@@ -1164,12 +1167,18 @@ def objects_by_sync_token(
11641167
This method transparently falls back to retrieving all objects if the server
11651168
doesn't support sync tokens. The fallback behavior is identical from the user's
11661169
perspective, but less efficient as it transfers the entire calendar on each sync.
1170+
1171+
If disable_fallback is set to True, the method will raise an exception instead
1172+
of falling back to retrieving all objects. This is useful for testing whether
1173+
the server truly supports sync tokens.
11671174
"""
11681175
## Check if we should attempt to use sync tokens
11691176
## (either server supports them, or we haven't checked yet, or this is a fake token)
11701177
use_sync_token = True
11711178
sync_support = self.client.features.is_supported("sync-token", return_type=dict)
11721179
if sync_support.get("support") == "unsupported":
1180+
if disable_fallback:
1181+
raise error.ReportError("Sync tokens are not supported by the server")
11731182
use_sync_token = False
11741183
## If sync_token looks like a fake token, don't try real sync-collection
11751184
if (
@@ -1210,6 +1219,8 @@ def objects_by_sync_token(
12101219
)
12111220
except (error.ReportError, error.DAVError) as e:
12121221
## Server doesn't support sync tokens or the sync-collection REPORT failed
1222+
if disable_fallback:
1223+
raise
12131224
log.info(
12141225
f"Sync-collection REPORT failed ({e}), falling back to full retrieval"
12151226
)

0 commit comments

Comments
 (0)