setup coverage
This commit is contained in:
parent
abe6497421
commit
999b824874
8 changed files with 46 additions and 23 deletions
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -9,4 +9,6 @@ jobs:
|
||||||
- name: Start
|
- name: Start
|
||||||
run: docker-compose -f test.yml up -d
|
run: docker-compose -f test.yml up -d
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: docker-compose -f test.yml run --entrypoint "" tests python -m unittest
|
run: docker-compose -f test.yml run --entrypoint "" tests ./tests/start.py
|
||||||
|
- name: "Upload coverage to Codecov"
|
||||||
|
uses: codecov/codecov-action@v1
|
||||||
|
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
coverage.xml
|
|
@ -2,7 +2,7 @@ FROM python:3.9-slim
|
||||||
|
|
||||||
EXPOSE 4785
|
EXPOSE 4785
|
||||||
|
|
||||||
RUN pip3 install --no-cache-dir markdown matrix-nio
|
RUN pip install --no-cache-dir markdown matrix-nio
|
||||||
|
|
||||||
ADD matrix_webhook.py /
|
ADD matrix_webhook.py /
|
||||||
|
|
||||||
|
|
10
test.yml
10
test.yml
|
@ -1,11 +1,11 @@
|
||||||
version: '3'
|
version: '3'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
bot:
|
|
||||||
build: .
|
|
||||||
env_file:
|
|
||||||
- tests/.env
|
|
||||||
tests:
|
tests:
|
||||||
build: tests
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: tests/Dockerfile
|
||||||
env_file:
|
env_file:
|
||||||
- tests/.env
|
- tests/.env
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
|
# Leverage a synapse base to be able to:
|
||||||
|
# "from synapse._scripts.register_new_matrix_user import request_registration"
|
||||||
FROM matrixdotorg/synapse
|
FROM matrixdotorg/synapse
|
||||||
|
|
||||||
# This defaults to /data which is a volume aiming at keeping data.
|
# This variable defaults to /data which is a volume made to keep data.
|
||||||
# Here, we want to trash those, and avoid the permission issues, so let's use something else
|
# Here, we want to trash those (and avoid the permission issues) by using something else
|
||||||
ENV SYNAPSE_CONFIG_DIR=/srv
|
ENV SYNAPSE_CONFIG_DIR=/srv
|
||||||
|
|
||||||
|
# Generate keys for synapse
|
||||||
WORKDIR $SYNAPSE_CONFIG_DIR
|
WORKDIR $SYNAPSE_CONFIG_DIR
|
||||||
|
ADD tests/homeserver.yaml .
|
||||||
ADD homeserver.yaml .
|
|
||||||
|
|
||||||
RUN python -m synapse.app.homeserver --config-path homeserver.yaml --generate-keys
|
RUN python -m synapse.app.homeserver --config-path homeserver.yaml --generate-keys
|
||||||
|
|
||||||
RUN chown -R 991:991 .
|
RUN chown -R 991:991 .
|
||||||
|
|
||||||
RUN python -m pip install aiohttp matrix-nio
|
RUN pip install --no-cache-dir aiohttp matrix-nio markdown coverage
|
||||||
|
|
||||||
ADD . .
|
WORKDIR /app
|
||||||
|
|
19
tests/start.py
Executable file
19
tests/start.py
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Entry point to start an instrumentalized bot for coverage and run tests."""
|
||||||
|
|
||||||
|
from subprocess import Popen, run
|
||||||
|
from unittest import main
|
||||||
|
|
||||||
|
|
||||||
|
def run_and_test():
|
||||||
|
"""Launch the bot and its tests."""
|
||||||
|
bot = Popen(['coverage', 'run', 'matrix_webhook.py'])
|
||||||
|
ret = main(module=None, exit=False).result.wasSuccessful()
|
||||||
|
bot.terminate()
|
||||||
|
for cmd in ['report', 'html', 'xml']:
|
||||||
|
run(['coverage', cmd])
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
exit(not run_and_test())
|
|
@ -6,7 +6,7 @@ import os
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import nio
|
import nio
|
||||||
|
|
||||||
from utils import MATRIX_ID, MATRIX_PW, MATRIX_URL, AbstractBotTest
|
from .utils import BOT_URL, MATRIX_ID, MATRIX_PW, MATRIX_URL, AbstractBotTest
|
||||||
|
|
||||||
KEY = os.environ['API_KEY']
|
KEY = os.environ['API_KEY']
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ class BotTest(AbstractBotTest):
|
||||||
async def test_errors(self):
|
async def test_errors(self):
|
||||||
"""Check the bot's error paths."""
|
"""Check the bot's error paths."""
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get('http://bot:4785') as response:
|
async with session.get(BOT_URL) as response:
|
||||||
self.assertEqual(await response.json(), {'status': 400, 'ret': 'Invalid JSON'})
|
self.assertEqual(await response.json(), {'status': 400, 'ret': 'Invalid JSON'})
|
||||||
async with session.post('http://bot:4785', data=json.dumps({'toto': 3})) as response:
|
async with session.post(BOT_URL, data=json.dumps({'toto': 3})) as response:
|
||||||
self.assertEqual(await response.json(), {'status': 400, 'ret': 'Missing text and/or API key property'})
|
self.assertEqual(await response.json(), {'status': 400, 'ret': 'Missing text and/or API key property'})
|
||||||
async with session.post('http://bot:4785', data=json.dumps({'text': 3, 'key': None})) as response:
|
async with session.post(BOT_URL, data=json.dumps({'text': 3, 'key': None})) as response:
|
||||||
self.assertEqual(await response.json(), {'status': 401, 'ret': 'Invalid API key'})
|
self.assertEqual(await response.json(), {'status': 401, 'ret': 'Invalid API key'})
|
||||||
async with session.post('http://bot:4785', data=json.dumps({'text': 3, 'key': KEY})) as response:
|
async with session.post(BOT_URL, data=json.dumps({'text': 3, 'key': KEY})) as response:
|
||||||
# TODO: we are not sending to a real room, so this should not be "OK"
|
# TODO: we are not sending to a real room, so this should not be "OK"
|
||||||
self.assertEqual(await response.json(), {'status': 200, 'ret': 'OK'})
|
self.assertEqual(await response.json(), {'status': 200, 'ret': 'OK'})
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class BotTest(AbstractBotTest):
|
||||||
|
|
||||||
room = await client.room_create()
|
room = await client.room_create()
|
||||||
|
|
||||||
url = f'http://bot:4785/{room.room_id}'
|
url = f'{BOT_URL}/{room.room_id}'
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(url, data=json.dumps({'text': text, 'key': KEY})) as response:
|
async with session.post(url, data=json.dumps({'text': text, 'key': KEY})) as response:
|
||||||
self.assertEqual(await response.json(), {'status': 200, 'ret': 'OK'})
|
self.assertEqual(await response.json(), {'status': 200, 'ret': 'OK'})
|
||||||
|
|
|
@ -8,6 +8,7 @@ import aiohttp
|
||||||
import yaml
|
import yaml
|
||||||
from synapse._scripts.register_new_matrix_user import request_registration
|
from synapse._scripts.register_new_matrix_user import request_registration
|
||||||
|
|
||||||
|
BOT_URL = 'http://localhost:4785'
|
||||||
MATRIX_URL, MATRIX_ID, MATRIX_PW = (os.environ[v] for v in ['MATRIX_URL', 'MATRIX_ID', 'MATRIX_PW'])
|
MATRIX_URL, MATRIX_ID, MATRIX_PW = (os.environ[v] for v in ['MATRIX_URL', 'MATRIX_ID', 'MATRIX_PW'])
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,11 +20,11 @@ class AbstractBotTest(unittest.IsolatedAsyncioTestCase):
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
all(await asyncio.gather(
|
all(await asyncio.gather(
|
||||||
wait_available(f'{MATRIX_URL}/_matrix/client/r0/login', 'flows'),
|
wait_available(f'{MATRIX_URL}/_matrix/client/r0/login', 'flows'),
|
||||||
wait_available('http://bot:4785/', 'status'),
|
wait_available(BOT_URL, 'status'),
|
||||||
)))
|
)))
|
||||||
|
|
||||||
# Try to register an user for the bot. Don't worry if it already exists.
|
# Try to register an user for the bot. Don't worry if it already exists.
|
||||||
with open('homeserver.yaml') as f:
|
with open('/srv/homeserver.yaml') as f:
|
||||||
secret = yaml.safe_load(f.read()).get("registration_shared_secret", None)
|
secret = yaml.safe_load(f.read()).get("registration_shared_secret", None)
|
||||||
request_registration(MATRIX_ID, MATRIX_PW, MATRIX_URL, secret, admin=False, user_type=None, exit=lambda x: x)
|
request_registration(MATRIX_ID, MATRIX_PW, MATRIX_URL, secret, admin=False, user_type=None, exit=lambda x: x)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue