neo4j-test-server 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- neo4j_test_server-0.1.0/.gitignore +19 -0
- neo4j_test_server-0.1.0/PKG-INFO +89 -0
- neo4j_test_server-0.1.0/README.md +71 -0
- neo4j_test_server-0.1.0/pyproject.toml +32 -0
- neo4j_test_server-0.1.0/src/neo4j_test_server/__init__.py +18 -0
- neo4j_test_server-0.1.0/src/neo4j_test_server/pytest_plugin.py +20 -0
- neo4j_test_server-0.1.0/src/neo4j_test_server/server.py +235 -0
- neo4j_test_server-0.1.0/tests/test_server.py +30 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: neo4j-test-server
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Disposable in-process Neo4j test server for Python integration tests
|
|
5
|
+
Author: vshofar
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: graph-database,integration-tests,neo4j,testing
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Topic :: Software Development :: Testing
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Requires-Dist: neo4j>=5.0
|
|
15
|
+
Provides-Extra: test
|
|
16
|
+
Requires-Dist: pytest>=7.0; extra == 'test'
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# neo4j-test-server (Python)
|
|
20
|
+
|
|
21
|
+
Pacote Python para subir um servidor Neo4j descartável em testes de integração.
|
|
22
|
+
|
|
23
|
+
O pacote baixa automaticamente o fat JAR do
|
|
24
|
+
[GitHub Releases](https://github.com/vshofar/neo4j-test-server/releases) na
|
|
25
|
+
primeira utilização e o cacheia localmente. Em runtime, apenas **Java 21+** é
|
|
26
|
+
necessário — nada de Gradle ou Maven.
|
|
27
|
+
|
|
28
|
+
## Instalação
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install neo4j-test-server
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Uso
|
|
35
|
+
|
|
36
|
+
### Context manager
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from neo4j_test_server import Neo4jTestServer
|
|
40
|
+
from neo4j import GraphDatabase
|
|
41
|
+
|
|
42
|
+
with Neo4jTestServer() as server:
|
|
43
|
+
driver = GraphDatabase.driver(
|
|
44
|
+
server.bolt_uri,
|
|
45
|
+
auth=(server.username, server.password),
|
|
46
|
+
)
|
|
47
|
+
with driver.session() as session:
|
|
48
|
+
session.run("CREATE (:Test {name: 'hello'})")
|
|
49
|
+
driver.close()
|
|
50
|
+
# servidor encerrado automaticamente
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Fixture pytest
|
|
54
|
+
|
|
55
|
+
O pacote registra automaticamente uma fixture `neo4j_test_server`
|
|
56
|
+
(session-scoped) via entry point `pytest11`:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
def test_something(neo4j_test_server):
|
|
60
|
+
driver = GraphDatabase.driver(
|
|
61
|
+
neo4j_test_server.bolt_uri,
|
|
62
|
+
auth=(neo4j_test_server.username, neo4j_test_server.password),
|
|
63
|
+
)
|
|
64
|
+
# ...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configuração
|
|
68
|
+
|
|
69
|
+
| Variável de ambiente | Descrição |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `NEO4J_TEST_SERVER_JAR` | Caminho para um JAR local (pula download) |
|
|
72
|
+
| `NEO4J_TEST_SERVER_CACHE` | Diretório de cache (padrão: `~/.cache/neo4j-test-server`) |
|
|
73
|
+
| `NEO4J_TEST_SERVER_JAR_VERSION` | Versão do JAR a baixar (padrão: versão fixada no pacote) |
|
|
74
|
+
| `JAVA_HOME` / `java` no PATH | Runtime Java 21+ |
|
|
75
|
+
|
|
76
|
+
## Desenvolvimento local
|
|
77
|
+
|
|
78
|
+
Para testar o pacote contra um JAR buildado localmente:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# na raiz do monorepo
|
|
82
|
+
./gradlew shadowJar
|
|
83
|
+
|
|
84
|
+
# aponte o pacote para o JAR local
|
|
85
|
+
export NEO4J_TEST_SERVER_JAR=$PWD/build/libs/neo4j-test-server-all.jar
|
|
86
|
+
|
|
87
|
+
# instale o pacote em modo editável
|
|
88
|
+
pip install -e python/
|
|
89
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# neo4j-test-server (Python)
|
|
2
|
+
|
|
3
|
+
Pacote Python para subir um servidor Neo4j descartável em testes de integração.
|
|
4
|
+
|
|
5
|
+
O pacote baixa automaticamente o fat JAR do
|
|
6
|
+
[GitHub Releases](https://github.com/vshofar/neo4j-test-server/releases) na
|
|
7
|
+
primeira utilização e o cacheia localmente. Em runtime, apenas **Java 21+** é
|
|
8
|
+
necessário — nada de Gradle ou Maven.
|
|
9
|
+
|
|
10
|
+
## Instalação
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install neo4j-test-server
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Uso
|
|
17
|
+
|
|
18
|
+
### Context manager
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from neo4j_test_server import Neo4jTestServer
|
|
22
|
+
from neo4j import GraphDatabase
|
|
23
|
+
|
|
24
|
+
with Neo4jTestServer() as server:
|
|
25
|
+
driver = GraphDatabase.driver(
|
|
26
|
+
server.bolt_uri,
|
|
27
|
+
auth=(server.username, server.password),
|
|
28
|
+
)
|
|
29
|
+
with driver.session() as session:
|
|
30
|
+
session.run("CREATE (:Test {name: 'hello'})")
|
|
31
|
+
driver.close()
|
|
32
|
+
# servidor encerrado automaticamente
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Fixture pytest
|
|
36
|
+
|
|
37
|
+
O pacote registra automaticamente uma fixture `neo4j_test_server`
|
|
38
|
+
(session-scoped) via entry point `pytest11`:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
def test_something(neo4j_test_server):
|
|
42
|
+
driver = GraphDatabase.driver(
|
|
43
|
+
neo4j_test_server.bolt_uri,
|
|
44
|
+
auth=(neo4j_test_server.username, neo4j_test_server.password),
|
|
45
|
+
)
|
|
46
|
+
# ...
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configuração
|
|
50
|
+
|
|
51
|
+
| Variável de ambiente | Descrição |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `NEO4J_TEST_SERVER_JAR` | Caminho para um JAR local (pula download) |
|
|
54
|
+
| `NEO4J_TEST_SERVER_CACHE` | Diretório de cache (padrão: `~/.cache/neo4j-test-server`) |
|
|
55
|
+
| `NEO4J_TEST_SERVER_JAR_VERSION` | Versão do JAR a baixar (padrão: versão fixada no pacote) |
|
|
56
|
+
| `JAVA_HOME` / `java` no PATH | Runtime Java 21+ |
|
|
57
|
+
|
|
58
|
+
## Desenvolvimento local
|
|
59
|
+
|
|
60
|
+
Para testar o pacote contra um JAR buildado localmente:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# na raiz do monorepo
|
|
64
|
+
./gradlew shadowJar
|
|
65
|
+
|
|
66
|
+
# aponte o pacote para o JAR local
|
|
67
|
+
export NEO4J_TEST_SERVER_JAR=$PWD/build/libs/neo4j-test-server-all.jar
|
|
68
|
+
|
|
69
|
+
# instale o pacote em modo editável
|
|
70
|
+
pip install -e python/
|
|
71
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "neo4j-test-server"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Disposable in-process Neo4j test server for Python integration tests"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "vshofar" }]
|
|
13
|
+
keywords = ["neo4j", "testing", "integration-tests", "graph-database"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development :: Testing",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"neo4j>=5.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
test = ["pytest>=7.0"]
|
|
27
|
+
|
|
28
|
+
[project.entry-points.pytest11]
|
|
29
|
+
neo4j_test_server = "neo4j_test_server.pytest_plugin"
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.targets.wheel]
|
|
32
|
+
packages = ["src/neo4j_test_server"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Disposable in-process Neo4j test server for Python integration tests."""
|
|
2
|
+
|
|
3
|
+
from neo4j_test_server.server import (
|
|
4
|
+
JAR_VERSION,
|
|
5
|
+
Neo4jTestServer,
|
|
6
|
+
ServerInfo,
|
|
7
|
+
ensure_jar,
|
|
8
|
+
jar_path,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"JAR_VERSION",
|
|
13
|
+
"Neo4jTestServer",
|
|
14
|
+
"ServerInfo",
|
|
15
|
+
"ensure_jar",
|
|
16
|
+
"jar_path",
|
|
17
|
+
]
|
|
18
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Pytest plugin exposing a session-scoped Neo4j test server fixture."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Iterator
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from neo4j_test_server.server import Neo4jTestServer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture(scope="session")
|
|
13
|
+
def neo4j_test_server() -> Iterator[Neo4jTestServer]:
|
|
14
|
+
"""Session-scoped fixture that starts the Neo4j test server once.
|
|
15
|
+
|
|
16
|
+
The server is shared by all tests in the session and shut down
|
|
17
|
+
automatically at the end.
|
|
18
|
+
"""
|
|
19
|
+
with Neo4jTestServer() as server:
|
|
20
|
+
yield server
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""Bootstrap and lifecycle management for the Neo4j test server JAR.
|
|
2
|
+
|
|
3
|
+
The server is a self-contained fat JAR published as a GitHub Release
|
|
4
|
+
asset. On first use it is downloaded and cached locally; only a Java
|
|
5
|
+
21+ runtime is required.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
import sys
|
|
15
|
+
import tempfile
|
|
16
|
+
import urllib.request
|
|
17
|
+
from dataclasses import dataclass
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import IO, Optional
|
|
20
|
+
|
|
21
|
+
JAR_VERSION = os.environ.get("NEO4J_TEST_SERVER_JAR_VERSION", "v0.1.0")
|
|
22
|
+
JAR_NAME = "neo4j-test-server-all.jar"
|
|
23
|
+
RELEASE_BASE_URL = (
|
|
24
|
+
"https://github.com/vshofar/neo4j-test-server/releases/download"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
DEFAULT_CACHE_DIR = (
|
|
28
|
+
Path(os.environ.get("NEO4J_TEST_SERVER_CACHE", ""))
|
|
29
|
+
if os.environ.get("NEO4J_TEST_SERVER_CACHE")
|
|
30
|
+
else Path.home() / ".cache" / "neo4j-test-server"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
STARTUP_TIMEOUT_SECONDS = 180
|
|
34
|
+
SHUTDOWN_TIMEOUT_SECONDS = 60
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class ServerInfo:
|
|
39
|
+
bolt_uri: str
|
|
40
|
+
username: str
|
|
41
|
+
password: str
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def jar_path(version: str = JAR_VERSION, cache_dir: Optional[Path] = None) -> Path:
|
|
45
|
+
"""Return the cached location of the JAR for a given version."""
|
|
46
|
+
return (cache_dir or DEFAULT_CACHE_DIR) / version / JAR_NAME
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def release_url(version: str = JAR_VERSION) -> str:
|
|
50
|
+
return f"{RELEASE_BASE_URL}/{version}/{JAR_NAME}"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def ensure_jar(
|
|
54
|
+
version: str = JAR_VERSION,
|
|
55
|
+
cache_dir: Optional[Path] = None,
|
|
56
|
+
url: Optional[str] = None,
|
|
57
|
+
) -> Path:
|
|
58
|
+
"""Return a local path to the JAR, downloading it if necessary.
|
|
59
|
+
|
|
60
|
+
Honors the ``NEO4J_TEST_SERVER_JAR`` environment variable, which
|
|
61
|
+
points directly to a local JAR and skips downloading entirely.
|
|
62
|
+
"""
|
|
63
|
+
override = os.environ.get("NEO4J_TEST_SERVER_JAR")
|
|
64
|
+
if override:
|
|
65
|
+
path = Path(override)
|
|
66
|
+
if not path.exists():
|
|
67
|
+
raise FileNotFoundError(f"NEO4J_TEST_SERVER_JAR not found: {path}")
|
|
68
|
+
return path
|
|
69
|
+
|
|
70
|
+
dest = jar_path(version, cache_dir)
|
|
71
|
+
if dest.exists():
|
|
72
|
+
return dest
|
|
73
|
+
|
|
74
|
+
url = url or release_url(version)
|
|
75
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
tmp = dest.with_suffix(".jar.part")
|
|
77
|
+
|
|
78
|
+
print(f"Downloading {JAR_NAME} ({version}) from {url} ...", file=sys.stderr)
|
|
79
|
+
try:
|
|
80
|
+
with urllib.request.urlopen(url) as response, open(tmp, "wb") as out:
|
|
81
|
+
shutil.copyfileobj(response, out, length=1024 * 1024)
|
|
82
|
+
tmp.replace(dest)
|
|
83
|
+
except Exception:
|
|
84
|
+
tmp.unlink(missing_ok=True)
|
|
85
|
+
raise
|
|
86
|
+
|
|
87
|
+
print(f"Cached at {dest}", file=sys.stderr)
|
|
88
|
+
return dest
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class Neo4jTestServer:
|
|
92
|
+
"""Context manager that runs the Neo4j test server as a subprocess.
|
|
93
|
+
|
|
94
|
+
Usage::
|
|
95
|
+
|
|
96
|
+
with Neo4jTestServer() as server:
|
|
97
|
+
driver = GraphDatabase.driver(
|
|
98
|
+
server.bolt_uri,
|
|
99
|
+
auth=(server.username, server.password),
|
|
100
|
+
)
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
jar: Optional[Path] = None,
|
|
106
|
+
java: str = "java",
|
|
107
|
+
working_dir: Optional[Path] = None,
|
|
108
|
+
env: Optional[dict] = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
self._jar = Path(jar) if jar else None
|
|
111
|
+
self._java = java
|
|
112
|
+
self._working_dir = working_dir
|
|
113
|
+
self._env = env
|
|
114
|
+
self._process: Optional[subprocess.Popen] = None
|
|
115
|
+
self._info: Optional[ServerInfo] = None
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def info(self) -> ServerInfo:
|
|
119
|
+
if self._info is None:
|
|
120
|
+
raise RuntimeError("server is not running")
|
|
121
|
+
return self._info
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def bolt_uri(self) -> str:
|
|
125
|
+
return self.info.bolt_uri
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def username(self) -> str:
|
|
129
|
+
return self.info.username
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def password(self) -> str:
|
|
133
|
+
return self.info.password
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def process(self) -> subprocess.Popen:
|
|
137
|
+
if self._process is None:
|
|
138
|
+
raise RuntimeError("server is not running")
|
|
139
|
+
return self._process
|
|
140
|
+
|
|
141
|
+
def start(self) -> ServerInfo:
|
|
142
|
+
if self._process is not None:
|
|
143
|
+
raise RuntimeError("server already running")
|
|
144
|
+
|
|
145
|
+
jar = self._jar or ensure_jar()
|
|
146
|
+
cmd = [self._java, "-jar", str(jar)]
|
|
147
|
+
if self._working_dir is not None:
|
|
148
|
+
cmd += ["--working-dir", str(self._working_dir)]
|
|
149
|
+
|
|
150
|
+
self._process = subprocess.Popen(
|
|
151
|
+
cmd,
|
|
152
|
+
stdin=subprocess.PIPE,
|
|
153
|
+
stdout=subprocess.PIPE,
|
|
154
|
+
stderr=None,
|
|
155
|
+
text=True,
|
|
156
|
+
env=self._env,
|
|
157
|
+
)
|
|
158
|
+
try:
|
|
159
|
+
self._info = self._read_ready(self._process)
|
|
160
|
+
except Exception:
|
|
161
|
+
self._terminate()
|
|
162
|
+
raise
|
|
163
|
+
return self._info
|
|
164
|
+
|
|
165
|
+
def stop(self) -> None:
|
|
166
|
+
if self._process is None:
|
|
167
|
+
return
|
|
168
|
+
process = self._process
|
|
169
|
+
self._process = None
|
|
170
|
+
self._info = None
|
|
171
|
+
|
|
172
|
+
if process.stdin:
|
|
173
|
+
try:
|
|
174
|
+
process.stdin.write("shutdown\n")
|
|
175
|
+
process.stdin.flush()
|
|
176
|
+
except (BrokenPipeError, OSError):
|
|
177
|
+
pass
|
|
178
|
+
try:
|
|
179
|
+
process.wait(timeout=SHUTDOWN_TIMEOUT_SECONDS)
|
|
180
|
+
except subprocess.TimeoutExpired:
|
|
181
|
+
process.kill()
|
|
182
|
+
process.wait()
|
|
183
|
+
|
|
184
|
+
def _read_ready(self, process: subprocess.Popen) -> ServerInfo:
|
|
185
|
+
stdout: IO[str] = process.stdout # type: ignore[assignment]
|
|
186
|
+
deadline = _monotonic() + STARTUP_TIMEOUT_SECONDS
|
|
187
|
+
for line in stdout:
|
|
188
|
+
line = line.strip()
|
|
189
|
+
if line.startswith("{"):
|
|
190
|
+
data = json.loads(line)
|
|
191
|
+
return ServerInfo(
|
|
192
|
+
bolt_uri=data["bolt_uri"],
|
|
193
|
+
username=data["username"],
|
|
194
|
+
password=data["password"],
|
|
195
|
+
)
|
|
196
|
+
if not process.poll() is None:
|
|
197
|
+
raise RuntimeError(
|
|
198
|
+
f"server exited before readiness message (code {process.returncode})"
|
|
199
|
+
)
|
|
200
|
+
if _monotonic() > deadline:
|
|
201
|
+
raise TimeoutError("timed out waiting for readiness message")
|
|
202
|
+
raise RuntimeError("server closed stdout before readiness message")
|
|
203
|
+
|
|
204
|
+
def _terminate(self) -> None:
|
|
205
|
+
process = self._process
|
|
206
|
+
self._process = None
|
|
207
|
+
self._info = None
|
|
208
|
+
if process is None:
|
|
209
|
+
return
|
|
210
|
+
if process.poll() is None:
|
|
211
|
+
process.kill()
|
|
212
|
+
process.wait()
|
|
213
|
+
|
|
214
|
+
def __enter__(self) -> "Neo4jTestServer":
|
|
215
|
+
self.start()
|
|
216
|
+
return self
|
|
217
|
+
|
|
218
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
219
|
+
self.stop()
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _monotonic() -> float:
|
|
223
|
+
import time
|
|
224
|
+
|
|
225
|
+
return time.monotonic()
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
__all__ = [
|
|
229
|
+
"JAR_VERSION",
|
|
230
|
+
"Neo4jTestServer",
|
|
231
|
+
"ServerInfo",
|
|
232
|
+
"ensure_jar",
|
|
233
|
+
"jar_path",
|
|
234
|
+
"release_url",
|
|
235
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Tests for the neo4j-test-server Python package.
|
|
2
|
+
|
|
3
|
+
Requires NEO4J_TEST_SERVER_JAR pointing to a built fat JAR
|
|
4
|
+
(see .github/workflows/build.yml).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from neo4j_test_server import Neo4jTestServer, ensure_jar
|
|
12
|
+
|
|
13
|
+
pytestmark = pytest.mark.skipif(
|
|
14
|
+
not os.environ.get("NEO4J_TEST_SERVER_JAR"),
|
|
15
|
+
reason="NEO4J_TEST_SERVER_JAR not set; skipping integration test",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_server_lifecycle() -> None:
|
|
20
|
+
with Neo4jTestServer() as server:
|
|
21
|
+
assert server.bolt_uri.startswith("bolt://")
|
|
22
|
+
assert server.username
|
|
23
|
+
assert server.password
|
|
24
|
+
assert server.process.poll() is None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_ensure_jar_uses_env_override() -> None:
|
|
28
|
+
path = ensure_jar()
|
|
29
|
+
assert path.exists()
|
|
30
|
+
assert path.name == "neo4j-test-server-all.jar"
|