diff options
-rw-r--r-- | pypaste/server/__init__.py | 10 | ||||
-rw-r--r-- | pypaste/server/s3/__init__.py | 6 | ||||
-rw-r--r-- | pypaste/server/sqlite/__init__.py | 6 | ||||
-rw-r--r-- | tests/meson.build | 2 | ||||
-rwxr-xr-x | tests/test_sqlite_storage.py | 103 |
5 files changed, 120 insertions, 7 deletions
diff --git a/pypaste/server/__init__.py b/pypaste/server/__init__.py index 5d6db32..67f8771 100644 --- a/pypaste/server/__init__.py +++ b/pypaste/server/__init__.py @@ -88,6 +88,10 @@ class Storage: pass @abstractmethod + async def exists(self, key: str) -> bool: + pass + + @abstractmethod async def vacuum(self, size: int) -> None: pass @@ -104,12 +108,6 @@ class Storage: case _: raise Exception("unreachable") - async def exists(self, key: str) -> bool: - async with self.connection.execute( - "select 1 from pastes where key=?", (key,) - ) as cursor: - return await cursor.fetchone() is not None - @dataclass class AppConfig: diff --git a/pypaste/server/s3/__init__.py b/pypaste/server/s3/__init__.py index d2cf7b2..6026fc4 100644 --- a/pypaste/server/s3/__init__.py +++ b/pypaste/server/s3/__init__.py @@ -91,6 +91,12 @@ class S3(Storage): await self.connection.rollback() raise e + async def exists(self, key: str) -> bool: + async with self.connection.execute( + "select 1 from s3 where key=?", (key,) + ) as cursor: + return await cursor.fetchone() is not None + async def vacuum(self, max: int) -> None: while True: async with self.connection.execute( diff --git a/pypaste/server/sqlite/__init__.py b/pypaste/server/sqlite/__init__.py index 2eb2ae5..c09e385 100644 --- a/pypaste/server/sqlite/__init__.py +++ b/pypaste/server/sqlite/__init__.py @@ -69,6 +69,12 @@ class Sqlite(Storage): await self.connection.execute("delete from sqlite where key=?", (key,)) + async def exists(self, key: str) -> bool: + async with self.connection.execute( + "select 1 from sqlite where key=?", (key,) + ) as cursor: + return await cursor.fetchone() is not None + async def vacuum(self, max: int) -> None: while True: async with self.connection.execute( diff --git a/tests/meson.build b/tests/meson.build index e39a559..801b30d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,4 +1,4 @@ -tests = files('test_server.py') +tests = files('test_server.py', 'test_sqlite_storage.py') foreach test : tests name = fs.stem(test) diff --git a/tests/test_sqlite_storage.py b/tests/test_sqlite_storage.py new file mode 100755 index 0000000..000d1a7 --- /dev/null +++ b/tests/test_sqlite_storage.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +import sys +import asyncio +import tempfile +import aiosqlite +import string +import random +from pypaste.server import Paste +from pypaste.server.sqlite import Sqlite +from datetime import datetime +from pathlib import Path + + +def truncate(path: Path) -> None: + with open(path, "w") as f: + f.truncate(0) + + +def generate_key() -> str: + chars = string.ascii_letters + + return "".join(random.choice(chars) for _ in range(10)) + + +async def test_exists_but_not_in_our_table(storage: Sqlite) -> None: + key = generate_key() + + await storage.connection.execute( + "insert into pastes values(?, ?, ?, ?)", + (key, datetime.now().isoformat(), None, bytes()), + ) + + assert not await storage.exists(key) + + +async def test_exists(storage: Sqlite) -> None: + dt = datetime.now() + key = generate_key() + + await storage.insert(Paste(key, dt, "test", "hello world")) + + assert await storage.exists(key) + + +async def test_delete(storage: Sqlite) -> None: + dt = datetime.now() + key = generate_key() + + await storage.insert(Paste(key, dt, "test", "hello world")) + + assert await storage.exists(key) + + await storage.delete(key) + + assert not await storage.exists(key) + + +async def test_insert_retrieve(storage: Sqlite) -> None: + dt = datetime.now() + key = generate_key() + + await storage.insert(Paste(key, dt, "test", "hello world")) + + paste = await storage.retrieve(key) + + assert paste is not None + assert paste.key == key + assert paste.dt == dt + assert paste.syntax == "test" + assert paste.text == "hello world" + + +async def main() -> int: + with tempfile.TemporaryDirectory() as tmpdir: + f = Path(tmpdir) / "database" + truncate(f) + async with aiosqlite.connect(f) as connection: + await connection.execute( + ( + "create table pastes(" + "key text," + "datetime text," + "size int," + "syntax text" + ")" + ) + ) + + storage = Sqlite(connection) + await storage.setup() + + await asyncio.gather( + test_insert_retrieve(storage), + test_delete(storage), + test_exists_but_not_in_our_table(storage), + ) + + return 0 + + +if __name__ == "__main__": + sys.exit(asyncio.run(main())) |