Skip to content

Commit

Permalink
Expanded build matrix to include EventStoreDB 22.10 and 23.10.
Browse files Browse the repository at this point in the history
Adjusted Makefile to support starting different server images, and to check for healthy containers.

Also adjusted README.md and test_docs.py, so application configuration is stated explicitly.
  • Loading branch information
johnbywater committed Nov 4, 2023
1 parent 49d5e77 commit 0e2d0be
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 96 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/github-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ jobs:
fail-fast: false
matrix:
python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
eventstoredb-version: [ "21-10" ]
os: [ ubuntu-20.04 ]
runs-on: ${{ matrix.os }}
eventstore-image-tag: [ "21.10.9-buster-slim", "22.10.3-buster-slim", "23.10.0-bookworm-slim" ]
env:
EVENTSTORE_IMAGE_TAG: ${{ matrix.eventstore-image-tag }}
runs-on: "ubuntu-22.04"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
Expand All @@ -25,9 +26,7 @@ jobs:
- name: Install packages
run: make install-packages
- name: Start EventStoreDB
run: |
make start-eventstoredb-${{ matrix.eventstoredb-version}}
sleep 60
run: make start-eventstoredb
- name: Lint
run: make lint
- name: Test
Expand Down
49 changes: 19 additions & 30 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ POETRY ?= poetry
POETRY_INSTALLER_URL ?= https://install.python-poetry.org
POETRY_VERSION=1.5.1

EVENTSTORE_IMAGE_NAME ?= eventstore/eventstore
EVENTSTORE_IMAGE_TAG ?= 23.10.0-bookworm-slim


.PHONY: install-poetry
install-poetry:
Expand Down Expand Up @@ -86,42 +89,23 @@ build:
publish:
$(POETRY) publish

.PHONY: start-eventstoredb-21-10-insecure
start-eventstoredb-21-10-insecure:
docker run -d -i -t -p 2114:2113 \
.PHONY: start-eventstoredb-insecure
start-eventstoredb-insecure:
docker run -d -i -t -p 2113:2113 \
--env "EVENTSTORE_ADVERTISE_HOST_TO_CLIENT_AS=localhost" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2114" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2113" \
--name my-eventstoredb-insecure \
eventstore/eventstore:21.10.9-buster-slim \
$(EVENTSTORE_IMAGE_NAME):$(EVENTSTORE_IMAGE_TAG) \
--insecure

.PHONY: start-eventstoredb-21-10-secure
start-eventstoredb-21-10-secure:
docker run -d -i -t -p 2115:2113 \
--env "HOME=/tmp" \
--env "EVENTSTORE_ADVERTISE_HOST_TO_CLIENT_AS=localhost" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2115" \
--name my-eventstoredb-secure \
eventstore/eventstore:21.10.9-buster-slim \
--dev

.PHONY: start-eventstoredb-22-10-insecure
start-eventstoredb-22-10-insecure:
.PHONY: start-eventstoredb-secure
start-eventstoredb-secure:
docker run -d -i -t -p 2114:2113 \
--env "EVENTSTORE_ADVERTISE_HOST_TO_CLIENT_AS=localhost" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2114" \
--name my-eventstoredb-insecure \
eventstore/eventstore:22.10.0-buster-slim \
--insecure

.PHONY: start-eventstoredb-22-10-secure
start-eventstoredb-22-10-secure:
docker run -d -i -t -p 2115:2113 \
--env "HOME=/tmp" \
--env "EVENTSTORE_ADVERTISE_HOST_TO_CLIENT_AS=localhost" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2115" \
--env "EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2114" \
--name my-eventstoredb-secure \
eventstore/eventstore:22.10.0-buster-slim \
$(EVENTSTORE_IMAGE_NAME):$(EVENTSTORE_IMAGE_TAG) \
--dev

.PHONY: attach-eventstoredb-insecure
Expand All @@ -142,8 +126,13 @@ stop-eventstoredb-secure:
docker stop my-eventstoredb-secure
docker rm my-eventstoredb-secure

.PHONY: start-eventstoredb-21-10
start-eventstoredb-21-10: start-eventstoredb-21-10-insecure start-eventstoredb-21-10-secure
.PHONY: start-eventstoredb
start-eventstoredb: start-eventstoredb-insecure start-eventstoredb-secure
@echo "Waiting for containers to be healthy"
@until docker ps | grep "my-eventstoredb" | grep -in "healthy" | wc -l | grep -in 2 > /dev/null; do printf "." && sleep 1; done; echo ""
@docker ps
@sleep 15


.PHONY: stop-eventstoredb
stop-eventstoredb: stop-eventstoredb-insecure stop-eventstoredb-secure
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,44 @@ class Dog(Aggregate):
self.tricks.append(trick)
```

Configure the application to use EventStoreDB. Set environment variable
`PERSISTENCE_MODULE` to `'eventsourcing_eventstoredb'` to use this package.
Configure the application to use EventStoreDB by setting the application environment
variable `PERSISTENCE_MODULE` to `'eventsourcing_eventstoredb'`. You can do this
in actual environment variables, by passing in an `env` argument when constructing
the application object, or by setting `env` on the application class.

Set environment variable `EVENTSTOREDB_URI` and to an EventStoreDB
```python
import os

os.environ['PERSISTENCE_MODULE'] = 'eventsourcing_eventstoredb'
```

Also set environment variable `EVENTSTOREDB_URI` and to an EventStoreDB
connection string URI. This value will be used as the `uri`
argument when the `ESDBClient` class is constructed by this package.

If you are connecting to a "secure" EventStoreDB server, please also set
```python
os.environ['EVENTSTOREDB_URI'] = 'esdb://localhost:2113?Tls=false'
```

If you are connecting to a "secure" EventStoreDB server, also set
environment variable `EVENTSTOREDB_ROOT_CERTIFICATES` to an SSL/TLS certificate
suitable for making a secure gRPC connection to the EventStoreDB server(s).
This value will be used as the `root_certificates` argument when the
`ESDBClient` class is constructed by this package.


```python
os.environ['EVENTSTOREDB_ROOT_CERTIFICATES'] = '<PEM encoded SSL/TLS root certificates>'
```

Please refer to the [esdbclient](https://github.com/pyeventsourcing/esdbclient)
documentation for details about starting a "secure" or "insecure" EventStoreDB
server, the "esdb" and "esdb+discover" EventStoreDB connection string
URI schemes, and how to obtain a suitable SSL/TLS certificate for use
in the client when connecting to a "secure" EventStoreDB server.

```python
school = TrainingSchool(env={
'PERSISTENCE_MODULE': 'eventsourcing_eventstoredb',
})
school = TrainingSchool()
```

Call application methods from tests and user interfaces.
Expand All @@ -95,9 +110,7 @@ To see the events have been saved, we can reconstruct the application
and get Fido's details again.

```python
school = TrainingSchool(env={
'PERSISTENCE_MODULE': 'eventsourcing_eventstoredb',
})
school = TrainingSchool()

dog_details = school.get_dog(dog_id)

Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# -*- coding: utf-8 -*-
INSECURE_CONNECTION_STRING = "esdb://localhost:2114?Tls=False"
INSECURE_CONNECTION_STRING = "esdb://localhost:2113?Tls=False"
117 changes: 68 additions & 49 deletions tests/test_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,22 @@

import os
import ssl
import sys
from pathlib import Path
from subprocess import PIPE, Popen
from tempfile import NamedTemporaryFile
from typing import List
from unittest import TestCase

from eventsourcing.utils import clear_topic_cache

BASE_DIR = Path(__file__).parents[1]


class TestDocs(TestCase):
def setUp(self) -> None:
self.setup_environ()

def setup_environ(self) -> None:
os.environ["EVENTSTOREDB_ROOT_CERTIFICATES"] = ssl.get_server_certificate(
addr=("localhost", 2115)
)
os.environ["EVENTSTOREDB_URI"] = "esdb://admin:changeit@localhost:2115"

def tearDown(self) -> None:
del os.environ["EVENTSTOREDB_URI"]
clear_topic_cache()
try:
del os.environ["EVENTSTOREDB_URI"]
except KeyError:
pass
try:
del os.environ["EVENTSTOREDB_ROOT_CERTIFICATES"]
except KeyError:
Expand Down Expand Up @@ -133,40 +128,64 @@ def check_code_snippets_in_file(self, doc_path: Path) -> None: # noqa: C901
last_line = orig_line

print(f"{num_code_lines} lines of code in {doc_path}")
self.substitute_lines(lines)

source = "\n".join(lines) + "\n"

exec(
compile(source=source, filename=doc_path, mode="exec"), globals(), globals()
)

# Write the code into a temp file.
with NamedTemporaryFile("w+") as tempfile:
source = "\n".join(lines) + "\n"
tempfile.writelines(source)
tempfile.flush()

print(Path.cwd())
print("\n".join(lines) + "\n")

# Run the code and catch errors.
env = os.environ.copy()
env["PYTHONPATH"] = str(BASE_DIR)

p = Popen(
[sys.executable, tempfile.name],
stdout=PIPE,
stderr=PIPE,
env=env,
)
print(sys.executable, tempfile.name, PIPE)
out, err = p.communicate()
decoded_out = out.decode("utf8").replace(tempfile.name, str(doc_path))
decoded_err = err.decode("utf8").replace(tempfile.name, str(doc_path))
exit_status = p.wait()

print(decoded_out)
print(decoded_err)

# Check for errors running the code.
if exit_status:
self.fail(decoded_out + decoded_err)


class TestDocsInsecure(TestDocs):
def setup_environ(self) -> None:
os.environ["EVENTSTOREDB_URI"] = "esdb://localhost:2114?Tls=false"
def substitute_lines(self, lines: List[str]) -> None:
pass

# # Write the code into a temp file.
# with NamedTemporaryFile("w+") as tempfile:
# source = "\n".join(lines) + "\n"
# tempfile.writelines(source)
# tempfile.flush()
#
# print(Path.cwd())
# print("\n".join(lines) + "\n")
#
# # Run the code and catch errors.
# env = os.environ.copy()
# env["PYTHONPATH"] = str(BASE_DIR)
#
# p = Popen(
# [sys.executable, tempfile.name],
# stdout=PIPE,
# stderr=PIPE,
# env=env,
# )
# print(sys.executable, tempfile.name, PIPE)
# out, err = p.communicate()
# decoded_out = out.decode("utf8").replace(tempfile.name, str(doc_path))
# decoded_err = err.decode("utf8").replace(tempfile.name, str(doc_path))
# exit_status = p.wait()
#
# print(decoded_out)
# print(decoded_err)
#
# # Check for errors running the code.
# if exit_status:
# self.fail(decoded_out + decoded_err)


class TestDocsSecure(TestDocs):
def substitute_lines(self, lines: List[str]) -> None:
for i in range(len(lines)):
line = lines[i]
if line.startswith("os.environ['EVENTSTOREDB_URI']"):
line = (
"os.environ['EVENTSTOREDB_URI'] ="
" 'esdb://admin:changeit@localhost:2114'"
)
elif line.startswith("os.environ['EVENTSTOREDB_ROOT_CERTIFICATES']"):
root_certificates = ssl.get_server_certificate(addr=("localhost", 2114))
root_certificates = "\\n".join(root_certificates.split("\n"))
line = (
"os.environ['EVENTSTOREDB_ROOT_CERTIFICATES'] = '%s'"
% root_certificates
)
lines[i] = line

0 comments on commit 0e2d0be

Please sign in to comment.