Test development Radicale again (#428)

* Revert "Don't test development Radicale"

This reverts commit 7a5241101e.

* Fix Radicale test setup

* Radicale is very tolerant

* Simplify test such that output is more predictable

* Runtime version check for Radicale

* Don't create user explicitly

* stylefix

* Shorter tracebacks

Travis logs are very hard to read
This commit is contained in:
Markus Unterwaditzer 2017-05-30 09:12:00 +02:00 committed by GitHub
parent 5f3c14ef7d
commit 7f80251527
7 changed files with 46 additions and 113 deletions

View file

@ -2,7 +2,6 @@
export DAV_SERVER := skip
export REMOTESTORAGE_SERVER := skip
export RADICALE_BACKEND := filesystem
export REQUIREMENTS := release
export TESTSERVER_BASE := ./tests/storage/servers/
export CI := false

View file

@ -3,6 +3,7 @@ universal = 1
[tool:pytest]
norecursedirs = tests/storage/servers/*
addopts = --tb=short
[flake8]
# E731: Use a def instead of lambda expr

View file

@ -322,11 +322,11 @@ class StorageTests(object):
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;TZID=Australia/Sydney:20140325T084000
DTEND;TZID=Australia/Sydney:20140325T101000
DTSTART;TZID=UTC:20140325T084000Z
DTEND;TZID=UTC:20140325T101000Z
DTSTAMP:20140327T060506Z
UID:{uid}
RECURRENCE-ID;TZID=Australia/Sydney:20140325T083000
RECURRENCE-ID;TZID=UTC:20140325T083000Z
CREATED:20131216T033331Z
DESCRIPTION:
LAST-MODIFIED:20140327T060215Z
@ -337,8 +337,8 @@ class StorageTests(object):
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Australia/Sydney:20140128T083000
DTEND;TZID=Australia/Sydney:20140128T100000
DTSTART;TZID=UTC:20140128T083000Z
DTEND;TZID=UTC:20140128T100000Z
RRULE:FREQ=WEEKLY;UNTIL=20141208T213000Z;BYDAY=TU
DTSTAMP:20140327T060506Z
UID:{uid}

View file

@ -24,12 +24,12 @@ ServerMixin = get_server_mixin(dav_server)
class DAVStorageTests(ServerMixin, StorageTests):
dav_server = dav_server
@pytest.mark.skipif(dav_server == 'radicale',
reason='Radicale is very tolerant.')
def test_dav_broken_item(self, s):
item = Item(u'HAHA:YES')
try:
with pytest.raises((exceptions.Error, requests.exceptions.HTTPError)):
s.upload(item)
except (exceptions.Error, requests.exceptions.HTTPError):
pass
assert not list(s.list())
def test_dav_empty_get_multi_performance(self, s, monkeypatch):

View file

@ -1,105 +1,42 @@
# -*- coding: utf-8 -*-
import os
import sys
from urllib.parse import quote as urlquote
import logging
import pytest
import radicale
import radicale.config
from pkg_resources import parse_version as ver
import wsgi_intercept
import wsgi_intercept.requests_intercept
RADICALE_SCHEMA = '''
create table collection (
path varchar(200) not null,
parent_path varchar(200) references collection (path),
primary key (path));
create table item (
name varchar(200) not null,
tag text not null,
collection_path varchar(200) references collection (path),
primary key (name));
create table header (
name varchar(200) not null,
value text not null,
collection_path varchar(200) references collection (path),
primary key (name, collection_path));
create table line (
name text not null,
value text not null,
item_name varchar(200) references item (name),
timestamp bigint not null,
primary key (timestamp));
create table property (
name varchar(200) not null,
value text not null,
collection_path varchar(200) references collection (path),
primary key (name, collection_path));
'''.split(';')
storage_backend = os.environ.get('RADICALE_BACKEND', '') or 'filesystem'
def do_the_radicale_dance(tmpdir):
# All of radicale is already global state, the cleanliness of the code and
# all hope is already lost. This function runs before every test.
# This wipes out the radicale modules, to reset all of its state.
for module in list(sys.modules):
if module.startswith('radicale'):
del sys.modules[module]
# radicale.config looks for this envvar. We have to delete it before it
# tries to load a config file.
os.environ['RADICALE_CONFIG'] = ''
import radicale.config
# Now we can set some basic configuration.
# Radicale <=0.7 doesn't work with this, therefore we just catch the
# exception and assume Radicale is open for everyone.
try:
radicale.config.set('rights', 'type', 'owner_only')
radicale.config.set('auth', 'type', 'http')
import radicale.auth.http
def is_authenticated(user, password):
return user == 'bob' and password == 'bob'
radicale.auth.http.is_authenticated = is_authenticated
except Exception as e:
print(e)
if storage_backend in ('filesystem', 'multifilesystem'):
radicale.config.set('storage', 'type', storage_backend)
radicale.config.set('storage', 'filesystem_folder', tmpdir)
elif storage_backend == 'database':
radicale.config.set('storage', 'type', 'database')
radicale.config.set('storage', 'database_url', 'sqlite://')
from radicale.storage import database
s = database.Session()
for line in RADICALE_SCHEMA:
s.execute(line)
s.commit()
else:
raise RuntimeError(storage_backend)
logger = logging.getLogger(__name__)
class ServerMixin(object):
@pytest.fixture(autouse=True)
def setup(self, request, tmpdir):
do_the_radicale_dance(str(tmpdir))
from radicale import Application
if ver(radicale.VERSION) < ver('2.0.0-pre'):
raise RuntimeError('Testing against Radicale only works with '
'Radicale >= 2.0.0')
def get_app():
config = radicale.config.load(())
config.set('storage', 'filesystem_folder', str(tmpdir))
config.set('rights', 'type', 'owner_only')
app = radicale.Application(config, logger)
def is_authenticated(user, password):
return user == 'bob' and password == 'bob'
app.is_authenticated = is_authenticated
return app
wsgi_intercept.requests_intercept.install()
wsgi_intercept.add_wsgi_intercept('127.0.0.1', 80, Application)
wsgi_intercept.add_wsgi_intercept('127.0.0.1', 80, get_app)
def teardown():
wsgi_intercept.remove_wsgi_intercept('127.0.0.1', 80)
@ -109,17 +46,14 @@ class ServerMixin(object):
@pytest.fixture
def get_storage_args(self, get_item):
def inner(collection='test'):
url = 'http://127.0.0.1/bob/'
if collection is not None:
collection += self.storage_class.fileext
url = url.rstrip('/') + '/' + urlquote(collection)
rv = {'url': url, 'username': 'bob', 'password': 'bob',
'collection': collection}
url = 'http://127.0.0.1/'
rv = {'url': url, 'username': 'bob', 'password': 'bob'}
if collection is not None:
collection = collection + self.storage_class.fileext
rv = self.storage_class.create_collection(collection, **rv)
s = self.storage_class(**rv)
s.delete(*s.upload(get_item()))
assert not list(s.list())
return rv
return inner

View file

@ -1,13 +1,12 @@
#!/bin/sh
set -e
if [ -z "$RADICALE_BACKEND" ]; then
echo "Missing RADICALE_BACKEND"
if [ "$REQUIREMENTS" = "release" ] || [ "$REQUIREMENTS" = "minimal" ]; then
radicale_pkg="radicale"
elif [ "$REQUIREMENTS" = "devel" ]; then
radicale_pkg="git+https://github.com/Kozea/Radicale.git"
else
echo "Invalid requirements envvar"
false
fi
pip install wsgi_intercept radicale
if [ "$RADICALE_BACKEND" = "database" ]; then
pip install sqlalchemy
fi
pip install wsgi_intercept $radicale_pkg

View file

@ -177,7 +177,7 @@ def request(method, url, session=None, latin1_fallback=True,
if r.status_code == 412:
raise exceptions.PreconditionFailed(r.reason)
if r.status_code == 404:
if r.status_code in (404, 410):
raise exceptions.NotFoundError(r.reason)
r.raise_for_status()