Skip to content

Commit cd15862

Browse files
authored
Add: run e2e test for local, git, github and gitlab storage backends (#348)
And while at it, cache the Python/Playwright installation files, to have everything up and running a lot quicker.
1 parent 95bd378 commit cd15862

5 files changed

Lines changed: 96 additions & 19 deletions

File tree

.coveragerc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[run]
2+
branch = True
3+
concurrency = multiprocessing
4+
parallel = True
5+
source = truewiki

.github/workflows/end-to-end.yml

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,46 @@ jobs:
1212
playwright:
1313
name: Playwright
1414
runs-on: ubuntu-latest
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
storage: [local, git, github, gitlab]
1519
steps:
1620
- name: Checkout
17-
uses: actions/checkout@v2
21+
uses: actions/checkout@v3
1822
- name: Set up Python 3.8
19-
uses: actions/setup-python@v1
23+
uses: actions/setup-python@v4
2024
with:
2125
python-version: 3.8
26+
cache: 'pip'
27+
cache-dependency-path: |
28+
e2e/requirements.base
29+
requirements.txt
30+
- uses: actions/cache@v3
31+
name: Cache Playwright
32+
id: playwright-cache
33+
with:
34+
path: '~/.cache/ms-playwright'
35+
key: '${{ runner.os }}-playwright'
2236
- name: Set up packages
2337
run: |
2438
python -m pip install --upgrade pip
2539
pip install -r e2e/requirements.base
2640
pip install -r requirements.txt
2741
playwright install
28-
- name: Playwright
42+
- name: Set up remote SSH keys
2943
run: |
30-
COVERAGE_FILE="$(pwd)/.coverage" pytest e2e
31-
- name: Coverage report
44+
mkdir -p ~/.ssh
45+
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
46+
ssh-keyscan -t rsa gitlab.com >> ~/.ssh/known_hosts
47+
- name: Playwright (storage=${{ matrix.storage }})
3248
run: |
49+
COVERAGE_RCFILE="$(pwd)/.coveragerc" COVERAGE_FILE="$(pwd)/.coverage" pytest e2e -v --storage ${{ matrix.storage }}
50+
coverage combine
3351
coverage report -m
34-
coverage html
3552
coverage xml
36-
- name: Archive coverage report
37-
uses: actions/upload-artifact@v3
38-
with:
39-
name: coverage-report
40-
path: htmlcov
53+
env:
54+
TRUEWIKI_STORAGE_GITHUB_PRIVATE_KEY: ${{ secrets.E2E_STORAGE_GITHUB_PRIVATE_KEY }}
55+
TRUEWIKI_STORAGE_GITLAB_PRIVATE_KEY: ${{ secrets.E2E_STORAGE_GITLAB_PRIVATE_KEY }}
4156
- name: Upload coverage to Codecov
4257
uses: codecov/codecov-action@v3

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ __pycache__/
22
*.pyc
33
/.cache_metadata.json
44
/.coverage
5+
/.coverage.*
56
/.env/
67
/data/
78
/cache/

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ This is located in the `e2e` folder, and requires some additional tooling to be
286286
```bash
287287
.env/bin/pip install -r e2e/requirements.txt
288288
.env/bin/playwright install
289-
COVERAGE_FILE="$(pwd)/.coverage" pytest e2e
289+
COVERAGE_RCFILE="$(pwd)/.coveragerc" COVERAGE_FILE="$(pwd)/.coverage" pytest e2e -v --storage local
290+
coverage combine
290291
coverage report -m
291292
```
292293

e2e/conftest.py

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55
import shutil
66
import signal
7+
import time
78

89
from ctypes.util import find_library
910
from tempfile import TemporaryDirectory
@@ -21,7 +22,7 @@ async def set_death_signal():
2122
libc.prctl(PR_SET_PDEATHSIG, signal.SIGTERM, 0, 0, 0)
2223

2324

24-
async def _run_server():
25+
async def _run_server(storage):
2526
global temp_folder, python_proc
2627

2728
# Make sure we can find our way to the code in the temporary folder.
@@ -43,18 +44,22 @@ async def _run_server():
4344
f.write("end-to-end test file")
4445
# Make sure a few languages exist.
4546
os.makedirs("data/Page/en")
47+
with open("data/Page/en/.keep", "w") as f:
48+
pass
4649
os.makedirs("data/Page/de")
50+
with open("data/Page/de/.keep", "w") as f:
51+
pass
4752

4853
# Run TrueWiki, with coverage enabled.
49-
command = ["coverage", "run", "--branch", "--source", "truewiki"]
54+
command = ["coverage", "run"]
5055
command.extend(
5156
[
5257
"-m",
5358
"truewiki",
5459
"--port",
5560
"8080",
5661
"--storage",
57-
"local",
62+
storage,
5863
"--user",
5964
"developer",
6065
"--frontend-url",
@@ -63,6 +68,35 @@ async def _run_server():
6368
"cache/",
6469
]
6570
)
71+
72+
if storage == "github":
73+
branch_name = "e2e-" + str(time.time()).replace(".", "-")
74+
75+
command.extend(
76+
[
77+
"--storage-github-url",
78+
"git@github.com:TrueBrain/truewiki-e2e-test.git",
79+
"--storage-github-history-url",
80+
"https://github.com/TrueBrain/truewiki-e2e-test",
81+
"--storage-github-branch",
82+
branch_name,
83+
]
84+
)
85+
86+
if storage == "gitlab":
87+
branch_name = "e2e-" + str(time.time()).replace(".", "-")
88+
89+
command.extend(
90+
[
91+
"--storage-gitlab-url",
92+
"git@gitlab.com:TrueBrain/truewiki-e2e-test.git",
93+
"--storage-gitlab-history-url",
94+
"https://gitlab.com/TrueBrain/truewiki-e2e-test",
95+
"--storage-gitlab-branch",
96+
branch_name,
97+
]
98+
)
99+
66100
python_proc = await asyncio.create_subprocess_exec(
67101
command[0],
68102
*command[1:],
@@ -72,17 +106,34 @@ async def _run_server():
72106
# Make sure we switch back to the project folder.
73107
os.chdir(cwd)
74108

75-
# Wait for the startup line to be shown.
76-
await python_proc.stdout.readline()
109+
# Wait till the server reports "running".
110+
lines = []
111+
while python_proc.returncode is None and not python_proc.stdout.at_eof():
112+
line = await python_proc.stdout.readline()
113+
if line is None:
114+
break
115+
lines.append(line)
116+
117+
if "Running on http://" in line.decode():
118+
break
119+
120+
# If either the process closed or the stdout closed, the server didn't
121+
# actual start. And yes, it can happen stdout is already closed, but
122+
# the returncode isn't in yet.
123+
if python_proc.returncode is not None or python_proc.stdout.at_eof():
124+
print((b"\n".join(lines) + await python_proc.stdout.read()).decode())
125+
raise Exception("Failed to start TrueWiki server")
126+
127+
return None
77128

78129

79130
@pytest.fixture(scope="session", autouse=True)
80-
def run_server():
131+
def run_server(request):
81132
# Create a new event loop for our server.
82133
loop = asyncio.new_event_loop()
83134

84135
# Start the server.
85-
loop.run_until_complete(_run_server())
136+
loop.run_until_complete(_run_server(request.config.getoption("--storage")))
86137

87138
# Give control back to PyTest.
88139
yield
@@ -93,6 +144,10 @@ def run_server():
93144
temp_folder.cleanup()
94145

95146

147+
def pytest_addoption(parser):
148+
parser.addoption("--storage", action="store", default="local", help="Storage backend")
149+
150+
96151
@pytest.fixture(autouse=True)
97152
def timeout(page: Page):
98153
page.set_default_timeout(1000)

0 commit comments

Comments
 (0)