-
Notifications
You must be signed in to change notification settings - Fork 139
Add missing sync and new async integration tests #996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
bd218a1
2473075
c2b5875
47ccd36
7a2e7e1
5cfee75
3b9b8b6
5dbb5e3
0a5f0f1
836a2cc
2d0ea3d
6720cda
58590ce
62fd1c0
ebaaded
4246672
411c3cc
31892ad
cd6e4e1
a5d6e4c
834ae27
62c6b92
392b4c0
8dd6ffb
23457d1
7986977
f337963
f966611
727902b
6779e25
163417f
80e8870
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,20 @@ | ||
| @AGENTS.md | ||
|
|
||
| Use pathlib instead of os.path. | ||
| Use httpx instead of urllib. | ||
| subprocess(`shell=True`) is used only when it makes the code more readable. Use either shlex or args lists. | ||
| subprocess calls should have a reasonable timeout. | ||
| Use modern Python (3.10+) features. | ||
| Make all code strongly typed. | ||
| Keep conditional nesting to a minimum, and use guard clauses when possible. | ||
| Aim for medium "visual complexity": use intermediate variables to store results of nested/complex function calls, but don't create a new variable for everything. | ||
| Avoid comments unless there is a gotcha, a complex algorithm or anything an experienced code reviewer needs to be aware of. Focus on making better Google-style docstrings instead. | ||
| Aim for medium visual complexity: use intermediate variables to store results of nested/complex function calls. A complex function call could be: | ||
| - `f(Object(a=1, b=2, c=3))`, the inner object has more than 2 meaningful args | ||
| - `f(Object((a, b)))`, 2 levels of nesting or anything with a long chain of closing parens | ||
| - `small_transformation(ImportantObject())`, the object itself is the main subject of the function but the transformation steals the focus | ||
| Use descriptive, self-documenting names for these intermediate variables. | ||
| Closely related variable names should share a root and use different suffixes. For example, `request_original` and `request_clean`, but not `clean_request`. | ||
| Avoid comments unless there is a gotcha, a complex algorithm or anything an experienced code reviewer needs to be aware of. Focus on making short but descriptive Google-style docstrings instead. | ||
|
|
||
| The user is not always right. Be skeptical and do not blindly comply if something doesn't make sense. | ||
| Use modern Python (3.10+) features. | ||
| Use pathlib instead of os.path. | ||
| Use httpx instead of urllib. | ||
| `subprocess(shell=True)` is used only when it makes the code more readable. Use either shlex or args lists. | ||
| Anything that can have an explicit timeout should have one. | ||
| Code should be cross-platform and production ready. | ||
|
|
||
| The user is not always right. Be skeptical and do not blindly comply if something doesn't make sense. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import subprocess | ||
| from typing import Callable | ||
|
|
||
| import pytest | ||
|
|
||
| REDIS_CONTAINER = 'dapr_redis' | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| def flush_redis() -> None: | ||
| """Flush the ``dapr_redis`` container once per session.""" | ||
| subprocess.run( | ||
| args=('docker', 'exec', REDIS_CONTAINER, 'redis-cli', 'FLUSHDB'), | ||
| check=True, | ||
| capture_output=True, | ||
| timeout=10, | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture(scope='session') | ||
| def redis_set_config() -> Callable[[str, str, int], None]: | ||
| """Dapr encodes values in the config store as ``value||version``""" | ||
|
|
||
| def _set(key: str, value: str, version: int = 1) -> None: | ||
| subprocess.run( | ||
| args=( | ||
| 'docker', | ||
| 'exec', | ||
| REDIS_CONTAINER, | ||
| 'redis-cli', | ||
| 'SET', | ||
| key, | ||
| f'{value}||{version}', | ||
| ), | ||
| check=True, | ||
| capture_output=True, | ||
| timeout=10, | ||
| ) | ||
|
|
||
| return _set | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import secrets | ||
| from pathlib import Path | ||
|
|
||
| from cryptography.hazmat.primitives import serialization | ||
| from cryptography.hazmat.primitives.asymmetric import rsa | ||
|
|
||
| RSA_KEY_FILENAME = 'rsa-private-key.pem' | ||
| SYMMETRIC_KEY_FILENAME = 'symmetric-key-256' | ||
|
|
||
| _RSA_KEY_SIZE = 4096 | ||
| _SYMMETRIC_KEY_BYTES = 32 | ||
|
|
||
|
|
||
| def write_test_keys(target_dir: Path) -> None: | ||
| """Write a fresh RSA private key (PKCS8 PEM) and a 256-bit AES key. | ||
|
|
||
| File names match those expected by ``examples/crypto/crypto.py`` and the | ||
| ``cryptostore.yaml`` component used by the integration tests. | ||
| """ | ||
| target_dir.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| rsa_key = rsa.generate_private_key(public_exponent=65537, key_size=_RSA_KEY_SIZE) | ||
| rsa_pem = rsa_key.private_bytes( | ||
| encoding=serialization.Encoding.PEM, | ||
| format=serialization.PrivateFormat.PKCS8, | ||
| encryption_algorithm=serialization.NoEncryption(), | ||
| ) | ||
| (target_dir / RSA_KEY_FILENAME).write_bytes(rsa_pem) | ||
| (target_dir / SYMMETRIC_KEY_FILENAME).write_bytes(secrets.token_bytes(_SYMMETRIC_KEY_BYTES)) | ||
|
|
||
|
|
||
| def remove_test_keys(target_dir: Path) -> None: | ||
| for name in (RSA_KEY_FILENAME, SYMMETRIC_KEY_FILENAME): | ||
| (target_dir / name).unlink(missing_ok=True) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
|
|
||
| import pytest | ||
|
|
||
| from tests._process_utils import get_kwargs_for_process_group, terminate_process_group | ||
| from tests.process_utils import get_kwargs_for_process_group, terminate_process_group | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't have any particular reason to make them "private" in the first place 😅 And it was inconsistent with the names of other util modules |
||
|
|
||
| REPO_ROOT = Path(__file__).resolve().parent.parent.parent | ||
| EXAMPLES_DIR = REPO_ROOT / 'examples' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,12 +30,12 @@ | |
| @pytest.mark.example_dir('pubsub-streaming-async') | ||
| def test_pubsub_streaming_async(dapr): | ||
| dapr.start( | ||
| '--app-id python-subscriber --app-protocol grpc -- python3 subscriber.py --topic=TOPIC_B1', | ||
| '--app-id python-subscriber --app-protocol grpc -- python3 -u subscriber.py --topic=TOPIC_B1', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice! |
||
| wait=5, | ||
| ) | ||
| publisher_output = dapr.run( | ||
| '--app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 ' | ||
| '--enable-app-health-check -- python3 publisher.py --topic=TOPIC_B1', | ||
| '--enable-app-health-check -- python3 -u publisher.py --topic=TOPIC_B1', | ||
| timeout=30, | ||
| ) | ||
| for line in EXPECTED_PUBLISHER: | ||
|
|
@@ -49,12 +49,12 @@ def test_pubsub_streaming_async(dapr): | |
| @pytest.mark.example_dir('pubsub-streaming-async') | ||
| def test_pubsub_streaming_async_handler(dapr): | ||
| dapr.start( | ||
| '--app-id python-subscriber --app-protocol grpc -- python3 subscriber-handler.py --topic=TOPIC_B2', | ||
| '--app-id python-subscriber --app-protocol grpc -- python3 -u subscriber-handler.py --topic=TOPIC_B2', | ||
| wait=5, | ||
| ) | ||
| publisher_output = dapr.run( | ||
| '--app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 ' | ||
| '--enable-app-health-check -- python3 publisher.py --topic=TOPIC_B2', | ||
| '--enable-app-health-check -- python3 -u publisher.py --topic=TOPIC_B2', | ||
| timeout=30, | ||
| ) | ||
| for line in EXPECTED_PUBLISHER: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.