From 14d649da11e1611c70b8d5042bdecaa41a5a60c4 Mon Sep 17 00:00:00 2001 From: Albert Callarisa Date: Tue, 24 Feb 2026 15:51:10 +0100 Subject: [PATCH] Try running examples in parallel Signed-off-by: Albert Callarisa --- examples/conversation/README.md | 6 +- .../real_llm_providers_example.py | 2 +- examples/demo_workflow/README.md | 2 +- examples/grpc_proxying/README.md | 12 +- .../grpc_proxying/deploy/invoke-caller.yaml | 2 +- .../grpc_proxying/deploy/invoke-receiver.yaml | 4 +- examples/grpc_proxying/invoke-caller.py | 2 +- examples/grpc_proxying/invoke-receiver.py | 2 +- examples/invoke-binding/README.md | 2 +- .../invoke-binding/invoke-input-binding.py | 2 +- examples/invoke-custom-data/README.md | 8 +- examples/invoke-custom-data/invoke-caller.py | 2 +- .../invoke-custom-data/invoke-receiver.py | 2 +- examples/invoke-http/README.md | 8 +- examples/invoke-http/invoke-caller.py | 4 +- examples/invoke-simple/README.md | 16 +- .../invoke-simple/deploy/invoke-caller.yaml | 2 +- .../invoke-simple/deploy/invoke-receiver.yaml | 4 +- examples/invoke-simple/invoke-caller.py | 2 +- examples/invoke-simple/invoke-receiver.py | 2 +- examples/jobs/README.md | 4 +- examples/jobs/job_processing.py | 2 +- examples/pubsub-simple/README.md | 8 +- examples/pubsub-simple/subscriber.py | 2 +- examples/pubsub-streaming-async/README.md | 8 +- examples/pubsub-streaming/README.md | 8 +- examples/state_store_query/README.md | 6 +- examples/validate.sh | 297 +++++++++++++++++- tox.ini | 48 +-- 29 files changed, 359 insertions(+), 110 deletions(-) diff --git a/examples/conversation/README.md b/examples/conversation/README.md index 1d7789b32..4042d52e6 100644 --- a/examples/conversation/README.md +++ b/examples/conversation/README.md @@ -102,7 +102,7 @@ The Conversation API supports real LLM providers including: Here we have a temporary directory with the component configurations with the API keys setup in the .env file. ```bash - dapr run --app-id test-app --dapr-http-port 3500 --dapr-grpc-port 50001 --resources-path + dapr run --app-id test-app --dapr-http-port 36001 --dapr-grpc-port 56001 --resources-path ``` For example if we have openai, anthropic, mistral, deepseek and google ai, we will have a temporary directory with the component configurations for each provider: @@ -126,7 +126,7 @@ The Conversation API supports real LLM providers including: /var/folders/3t/b6jkjnv970l6dd1sp81b19hw0000gn/T/dapr-llm-components-9mcpb1a3 To start the sidecar with these components: - dapr run --app-id test-app --dapr-http-port 3500 --dapr-grpc-port 50001 --resources-path /var/folders/3t/b6jkjnv970l6dd1sp81b19hw0000gn/T/dapr-llm-components-9mcpb1a3 + dapr run --app-id test-app --dapr-http-port 36001 --dapr-grpc-port 56001 --resources-path /var/folders/3t/b6jkjnv970l6dd1sp81b19hw0000gn/T/dapr-llm-components-9mcpb1a3 Press Enter when Dapr sidecar is running with the component configurations... ``` @@ -504,7 +504,7 @@ spec: ### Running with Dapr Sidecar ```bash # The example creates temporary component configs and shows you the command: -dapr run --app-id test-app --dapr-http-port 3500 --dapr-grpc-port 50001 --resources-path /tmp/dapr-llm-components-xyz/ +dapr run --app-id test-app --dapr-http-port 36001 --dapr-grpc-port 56001 --resources-path /tmp/dapr-llm-components-xyz/ ``` diff --git a/examples/conversation/real_llm_providers_example.py b/examples/conversation/real_llm_providers_example.py index 2347f4b50..952d1395d 100644 --- a/examples/conversation/real_llm_providers_example.py +++ b/examples/conversation/real_llm_providers_example.py @@ -1224,7 +1224,7 @@ def main(): print(f' {components_dir}') print('\nTo start the sidecar with these components:') print( - f' dapr run --app-id test-app --dapr-http-port 3500 --dapr-grpc-port 50001 --resources-path {components_dir}' + f' dapr run --app-id test-app --dapr-http-port 36001 --dapr-grpc-port 56001 --resources-path {components_dir}' ) # Wait for user to confirm diff --git a/examples/demo_workflow/README.md b/examples/demo_workflow/README.md index cf75112a2..4bff7f523 100644 --- a/examples/demo_workflow/README.md +++ b/examples/demo_workflow/README.md @@ -53,7 +53,7 @@ sleep: 15 --> ```sh -dapr run --app-id orderapp --app-protocol grpc --dapr-grpc-port 50001 --resources-path components --placement-host-address localhost:50005 -- python3 app.py +dapr run --app-id orderapp --app-protocol grpc --dapr-grpc-port 56013 --resources-path components --placement-host-address localhost:50005 -- python3 app.py ``` diff --git a/examples/grpc_proxying/README.md b/examples/grpc_proxying/README.md index 73b4fafe5..4563417ef 100644 --- a/examples/grpc_proxying/README.md +++ b/examples/grpc_proxying/README.md @@ -31,7 +31,7 @@ sleep: 5 ```bash # 1. Start Receiver (expose gRPC server receiver on port 50051) -dapr run --app-id invoke-receiver --app-protocol grpc --app-port 50051 --config config.yaml -- python invoke-receiver.py +dapr run --app-id grpc-proxying-receiver --app-protocol grpc --app-port 51056 --config config.yaml -- python invoke-receiver.py ``` @@ -50,7 +50,7 @@ sleep: 5 ```bash # 2. Start Caller -dapr run --app-id invoke-caller --dapr-grpc-port 50007 --config config.yaml -- python invoke-caller.py +dapr run --app-id grpc-proxying-caller --dapr-grpc-port 50007 --config config.yaml -- python invoke-caller.py ``` @@ -59,12 +59,12 @@ dapr run --app-id invoke-caller --dapr-grpc-port 50007 --config config.yaml -- ```bash -dapr stop --app-id invoke-receiver +dapr stop --app-id grpc-proxying-receiver ``` @@ -95,7 +95,7 @@ dapr stop --app-id invoke-receiver Logs for caller sidecar: ``` - dapr logs -a invoke-caller -k + dapr logs -a grpc-proxying-caller -k ``` Logs for caller app: @@ -105,7 +105,7 @@ dapr stop --app-id invoke-receiver Logs for receiver sidecar: ``` - dapr logs -a invoke-receiver -k + dapr logs -a grpc-proxying-receiver -k ``` Logs for receiver app: diff --git a/examples/grpc_proxying/deploy/invoke-caller.yaml b/examples/grpc_proxying/deploy/invoke-caller.yaml index 819152eb3..237504826 100644 --- a/examples/grpc_proxying/deploy/invoke-caller.yaml +++ b/examples/grpc_proxying/deploy/invoke-caller.yaml @@ -26,7 +26,7 @@ spec: app: invokecaller annotations: dapr.io/enabled: "true" - dapr.io/app-id: "invoke-caller" + dapr.io/app-id: "grpc-proxying-caller" dapr.io/app-protocol: "grpc" spec: containers: diff --git a/examples/grpc_proxying/deploy/invoke-receiver.yaml b/examples/grpc_proxying/deploy/invoke-receiver.yaml index 3f7958f3d..6688ddd92 100644 --- a/examples/grpc_proxying/deploy/invoke-receiver.yaml +++ b/examples/grpc_proxying/deploy/invoke-receiver.yaml @@ -26,9 +26,9 @@ spec: app: invokereceiver annotations: dapr.io/enabled: "true" - dapr.io/app-id: "invoke-receiver" + dapr.io/app-id: "grpc-proxying-receiver" dapr.io/app-protocol: "grpc" - dapr.io/app-port: "50051" + dapr.io/app-port: "51056" spec: containers: - name: invokereceiver diff --git a/examples/grpc_proxying/invoke-caller.py b/examples/grpc_proxying/invoke-caller.py index eead69da3..7aea11575 100644 --- a/examples/grpc_proxying/invoke-caller.py +++ b/examples/grpc_proxying/invoke-caller.py @@ -8,7 +8,7 @@ async def run() -> None: async with grpc.aio.insecure_channel('127.0.0.1:50007') as channel: - metadata = (('dapr-app-id', 'invoke-receiver'),) + metadata = (('dapr-app-id', 'grpc-proxying-receiver'),) stub = helloworld_service_pb2_grpc.HelloWorldServiceStub(channel) response = await stub.SayHello(request=HelloRequest(name='you'), metadata=metadata) print('Greeter client received: ' + response.message) diff --git a/examples/grpc_proxying/invoke-receiver.py b/examples/grpc_proxying/invoke-receiver.py index 0a140ff79..26e8326ad 100644 --- a/examples/grpc_proxying/invoke-receiver.py +++ b/examples/grpc_proxying/invoke-receiver.py @@ -20,4 +20,4 @@ def SayHello(self, request: HelloRequest, context: grpc.aio.ServicerContext) -> app.add_external_service( helloworld_service_pb2_grpc.add_HelloWorldServiceServicer_to_server, HelloWorldService() ) - app.run(50051) + app.run(51056) diff --git a/examples/invoke-binding/README.md b/examples/invoke-binding/README.md index c90ff1dfc..1f00c5ded 100644 --- a/examples/invoke-binding/README.md +++ b/examples/invoke-binding/README.md @@ -47,7 +47,7 @@ sleep: 5 2. Start Receiver (expose gRPC server receiver on port 50051) ```bash -dapr run --app-id receiver --app-protocol grpc --app-port 50051 --resources-path ./components python3 invoke-input-binding.py +dapr run --app-id receiver --app-protocol grpc --app-port 51053 --resources-path ./components python3 invoke-input-binding.py ``` diff --git a/examples/invoke-binding/invoke-input-binding.py b/examples/invoke-binding/invoke-input-binding.py index f87011691..13a6b21fd 100644 --- a/examples/invoke-binding/invoke-input-binding.py +++ b/examples/invoke-binding/invoke-input-binding.py @@ -8,4 +8,4 @@ def binding(request: BindingRequest): print(request.text(), flush=True) -app.run(50051) +app.run(51053) diff --git a/examples/invoke-custom-data/README.md b/examples/invoke-custom-data/README.md index 6c1f87f19..1f331a133 100644 --- a/examples/invoke-custom-data/README.md +++ b/examples/invoke-custom-data/README.md @@ -39,7 +39,7 @@ sleep: 5 --> ```bash - dapr run --app-id invoke-receiver --app-protocol grpc --app-port 50051 python3 invoke-receiver.py + dapr run --app-id invoke-custom-data-receiver --app-protocol grpc --app-port 51052 python3 invoke-receiver.py ``` @@ -58,7 +58,7 @@ sleep: 5 --> ```bash - dapr run --app-id invoke-caller --app-protocol grpc python3 invoke-caller.py + dapr run --app-id invoke-custom-data-caller --app-protocol grpc python3 invoke-caller.py ``` @@ -83,12 +83,12 @@ Expected output from receiver: ```bash -dapr stop --app-id invoke-receiver +dapr stop --app-id invoke-custom-data-receiver ``` diff --git a/examples/invoke-custom-data/invoke-caller.py b/examples/invoke-custom-data/invoke-caller.py index caeb84313..519433fa0 100644 --- a/examples/invoke-custom-data/invoke-caller.py +++ b/examples/invoke-custom-data/invoke-caller.py @@ -5,7 +5,7 @@ with DaprClient() as d: # Create a typed message with content type and body resp = d.invoke_method( - app_id='invoke-receiver', + app_id='invoke-custom-data-receiver', method_name='my_method', data=b'SOME_DATA', content_type='text/plain; charset=UTF-8', diff --git a/examples/invoke-custom-data/invoke-receiver.py b/examples/invoke-custom-data/invoke-receiver.py index 543d4fceb..706e3729c 100644 --- a/examples/invoke-custom-data/invoke-receiver.py +++ b/examples/invoke-custom-data/invoke-receiver.py @@ -14,4 +14,4 @@ def mymethod(request: InvokeMethodRequest): ) -app.run(50051) +app.run(51052) diff --git a/examples/invoke-http/README.md b/examples/invoke-http/README.md index 042faf11e..bcb6d3542 100644 --- a/examples/invoke-http/README.md +++ b/examples/invoke-http/README.md @@ -42,7 +42,7 @@ sleep: 5 --> ```bash -dapr run --app-id=invoke-receiver --app-port=8088 --app-protocol http -- python3 invoke-receiver.py +dapr run --app-id=invoke-http-receiver --app-port=8088 --app-protocol http -- python3 invoke-receiver.py ``` @@ -63,7 +63,7 @@ sleep: 5 --> ```bash -dapr run --app-id=invoke-caller -- python3 invoke-caller.py +dapr run --app-id=invoke-http-caller -- python3 invoke-caller.py ``` @@ -71,12 +71,12 @@ dapr run --app-id=invoke-caller -- python3 invoke-caller.py ```bash -dapr stop --app-id invoke-receiver +dapr stop --app-id invoke-http-receiver ``` diff --git a/examples/invoke-http/invoke-caller.py b/examples/invoke-http/invoke-caller.py index 115f20ec0..caccf4bea 100644 --- a/examples/invoke-http/invoke-caller.py +++ b/examples/invoke-http/invoke-caller.py @@ -9,7 +9,7 @@ # First message: success # Create a typed message with content type and body resp1 = d.invoke_method( - 'invoke-receiver', + 'invoke-http-receiver', 'my-method', http_verb='POST', data=json.dumps(req_data), @@ -24,7 +24,7 @@ req_data = {'id': 2, 'message': 'hello world'} try: resp2 = d.invoke_method( - 'invoke-receiver', + 'invoke-http-receiver', 'my-method-err', http_verb='POST', data=json.dumps(req_data), diff --git a/examples/invoke-simple/README.md b/examples/invoke-simple/README.md index b2af5c60f..98a43c16e 100644 --- a/examples/invoke-simple/README.md +++ b/examples/invoke-simple/README.md @@ -32,7 +32,7 @@ sleep: 5 ```bash # 1. Start Receiver (expose gRPC server receiver on port 50051) -dapr run --app-id invoke-receiver --app-protocol grpc --app-port 50051 python3 invoke-receiver.py +dapr run --app-id invoke-simple-receiver --app-protocol grpc --app-port 51051 python3 invoke-receiver.py ``` @@ -52,7 +52,7 @@ sleep: 5 ```bash # 2. Start Caller -dapr run --app-id invoke-caller --app-protocol grpc --dapr-http-port 3500 python3 invoke-caller.py +dapr run --app-id invoke-simple-caller --app-protocol grpc --dapr-http-port 36003 python3 invoke-caller.py ``` @@ -61,14 +61,14 @@ dapr run --app-id invoke-caller --app-protocol grpc --dapr-http-port 3500 python ```bash -dapr stop --app-id invoke-caller -dapr stop --app-id invoke-receiver +dapr stop --app-id invoke-simple-caller +dapr stop --app-id invoke-simple-receiver ``` @@ -99,7 +99,7 @@ dapr stop --app-id invoke-receiver Logs for caller sidecar: ``` - dapr logs -a invoke-caller -k + dapr logs -a invoke-simple-caller -k ``` Logs for caller app: @@ -109,7 +109,7 @@ dapr stop --app-id invoke-receiver Logs for receiver sidecar: ``` - dapr logs -a invoke-receiver -k + dapr logs -a invoke-simple-receiver -k ``` Logs for receiver app: diff --git a/examples/invoke-simple/deploy/invoke-caller.yaml b/examples/invoke-simple/deploy/invoke-caller.yaml index 0c60fd6f8..30d8b09e0 100644 --- a/examples/invoke-simple/deploy/invoke-caller.yaml +++ b/examples/invoke-simple/deploy/invoke-caller.yaml @@ -26,7 +26,7 @@ spec: app: invokecaller annotations: dapr.io/enabled: "true" - dapr.io/app-id: "invoke-caller" + dapr.io/app-id: "invoke-simple-caller" dapr.io/app-protocol: "grpc" spec: containers: diff --git a/examples/invoke-simple/deploy/invoke-receiver.yaml b/examples/invoke-simple/deploy/invoke-receiver.yaml index 07cd4804a..c3c588c49 100644 --- a/examples/invoke-simple/deploy/invoke-receiver.yaml +++ b/examples/invoke-simple/deploy/invoke-receiver.yaml @@ -26,9 +26,9 @@ spec: app: invokereceiver annotations: dapr.io/enabled: "true" - dapr.io/app-id: "invoke-receiver" + dapr.io/app-id: "invoke-simple-receiver" dapr.io/app-protocol: "grpc" - dapr.io/app-port: "50051" + dapr.io/app-port: "51051" spec: containers: - name: invokereceiver diff --git a/examples/invoke-simple/invoke-caller.py b/examples/invoke-simple/invoke-caller.py index 5c5773ea2..410e327c6 100644 --- a/examples/invoke-simple/invoke-caller.py +++ b/examples/invoke-simple/invoke-caller.py @@ -9,7 +9,7 @@ while True: # Create a typed message with content type and body resp = d.invoke_method( - 'invoke-receiver', + 'invoke-simple-receiver', 'my-method', data=json.dumps(req_data), ) diff --git a/examples/invoke-simple/invoke-receiver.py b/examples/invoke-simple/invoke-receiver.py index 2d1f0c2ee..9e2be5dbf 100644 --- a/examples/invoke-simple/invoke-receiver.py +++ b/examples/invoke-simple/invoke-receiver.py @@ -11,4 +11,4 @@ def mymethod(request: InvokeMethodRequest) -> InvokeMethodResponse: return InvokeMethodResponse(b'INVOKE_RECEIVED', 'text/plain; charset=UTF-8') -app.run(50051) +app.run(51051) diff --git a/examples/jobs/README.md b/examples/jobs/README.md index 3e2417472..ee1b8d304 100644 --- a/examples/jobs/README.md +++ b/examples/jobs/README.md @@ -93,7 +93,7 @@ sleep: 15 ```bash # Start the complete workflow example (schedules jobs and handles job events) -dapr run --app-id jobs-workflow --app-protocol grpc --app-port 50051 python3 job_processing.py +dapr run --app-id jobs-workflow --app-protocol grpc --app-port 51054 python3 job_processing.py ``` @@ -238,7 +238,7 @@ def handle_my_job(job_event: JobEvent) -> None: print(f"Job data: {data_str}") # Process the job... -app.run(50051) +app.run(51054) ``` The callback service must: diff --git a/examples/jobs/job_processing.py b/examples/jobs/job_processing.py index 6d384cbb0..8587c85d9 100644 --- a/examples/jobs/job_processing.py +++ b/examples/jobs/job_processing.py @@ -136,4 +136,4 @@ def schedule_jobs(): threading.Thread(target=schedule_jobs, daemon=True).start() print('Starting gRPC server on port 50051...', flush=True) - app.run(50051) + app.run(51054) diff --git a/examples/pubsub-simple/README.md b/examples/pubsub-simple/README.md index 6ee7ad89d..86681e81d 100644 --- a/examples/pubsub-simple/README.md +++ b/examples/pubsub-simple/README.md @@ -53,7 +53,7 @@ sleep: 3 ```bash # 1. Start Subscriber (expose gRPC server receiver on port 50051) -dapr run --app-id python-subscriber --app-protocol grpc --app-port 50051 -- python3 subscriber.py +dapr run --app-id pubsub-simple-subscriber --app-protocol grpc --app-port 51055 -- python3 subscriber.py ``` @@ -79,7 +79,7 @@ sleep: 15 ```bash # 2. Start Publisher -dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --enable-app-health-check python3 publisher.py +dapr run --app-id pubsub-simple-publisher --app-protocol grpc --dapr-grpc-port=56010 --enable-app-health-check python3 publisher.py ``` @@ -88,12 +88,12 @@ dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --e ```bash -dapr stop --app-id python-subscriber +dapr stop --app-id pubsub-simple-subscriber ``` diff --git a/examples/pubsub-simple/subscriber.py b/examples/pubsub-simple/subscriber.py index 4d36f2807..7b3c3c5e5 100644 --- a/examples/pubsub-simple/subscriber.py +++ b/examples/pubsub-simple/subscriber.py @@ -127,4 +127,4 @@ def mytopic_wildcard(event: v1.Event) -> TopicEventResponse: app.register_health_check(lambda: print('Healthy')) -app.run(50051) +app.run(51055) diff --git a/examples/pubsub-streaming-async/README.md b/examples/pubsub-streaming-async/README.md index e626fe75a..d8b37834f 100644 --- a/examples/pubsub-streaming-async/README.md +++ b/examples/pubsub-streaming-async/README.md @@ -41,7 +41,7 @@ sleep: 3 ```bash # 1. Start Subscriber -dapr run --app-id python-subscriber --app-protocol grpc -- python3 subscriber.py --topic=TOPIC_B1 +dapr run --app-id pubsub-streaming-async-subscriber --app-protocol grpc -- python3 subscriber.py --topic=TOPIC_B1 ``` @@ -63,7 +63,7 @@ sleep: 15 ```bash # 2. Start Publisher -dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_B1 +dapr run --app-id pubsub-streaming-async-publisher --app-protocol grpc --dapr-grpc-port=56012 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_B1 ``` @@ -89,7 +89,7 @@ sleep: 3 ```bash # 1. Start Subscriber -dapr run --app-id python-subscriber --app-protocol grpc -- python3 subscriber-handler.py --topic=TOPIC_B2 +dapr run --app-id pubsub-streaming-async-subscriber --app-protocol grpc -- python3 subscriber-handler.py --topic=TOPIC_B2 ``` @@ -111,7 +111,7 @@ sleep: 15 ```bash # 2. Start Publisher -dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_B2 +dapr run --app-id pubsub-streaming-async-publisher --app-protocol grpc --dapr-grpc-port=56012 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_B2 ``` diff --git a/examples/pubsub-streaming/README.md b/examples/pubsub-streaming/README.md index 40a746d3e..ff9b24a12 100644 --- a/examples/pubsub-streaming/README.md +++ b/examples/pubsub-streaming/README.md @@ -41,7 +41,7 @@ sleep: 3 ```bash # 1. Start Subscriber -dapr run --app-id python-subscriber --app-protocol grpc -- python3 subscriber.py --topic=TOPIC_A1 +dapr run --app-id pubsub-streaming-subscriber --app-protocol grpc -- python3 subscriber.py --topic=TOPIC_A1 ``` @@ -63,7 +63,7 @@ sleep: 15 ```bash # 2. Start Publisher -dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_A1 +dapr run --app-id pubsub-streaming-publisher --app-protocol grpc --dapr-grpc-port=56011 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_A1 ``` @@ -89,7 +89,7 @@ sleep: 3 ```bash # 1. Start Subscriber -dapr run --app-id python-subscriber --app-protocol grpc -- python3 subscriber-handler.py --topic=TOPIC_A2 +dapr run --app-id pubsub-streaming-subscriber --app-protocol grpc -- python3 subscriber-handler.py --topic=TOPIC_A2 ``` @@ -111,7 +111,7 @@ sleep: 15 ```bash # 2. Start Publisher -dapr run --app-id python-publisher --app-protocol grpc --dapr-grpc-port=3500 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_A2 +dapr run --app-id pubsub-streaming-publisher --app-protocol grpc --dapr-grpc-port=56011 --enable-app-health-check -- python3 publisher.py --topic=TOPIC_A2 ``` diff --git a/examples/state_store_query/README.md b/examples/state_store_query/README.md index 1c257d081..f8a17ac46 100644 --- a/examples/state_store_query/README.md +++ b/examples/state_store_query/README.md @@ -25,7 +25,7 @@ timeout_seconds: 120 --> ```bash -docker run -d --rm -p 27017:27017 --name mongodb mongo:5 +docker run -d --rm -p 27017:27017 --name state-store-query-mongodb mongo:5 ``` @@ -46,7 +46,7 @@ timeout_seconds: 10 ```bash # Import the example dataset -dapr run --app-id demo --dapr-http-port 3500 --resources-path components -- curl -X POST -H "Content-Type: application/json" -d @dataset.json http://localhost:3500/v1.0/state/statestore +dapr run --app-id demo --dapr-http-port 36002 --resources-path components -- curl -X POST -H "Content-Type: application/json" -d @dataset.json http://localhost:36002/v1.0/state/statestore ``` @@ -94,7 +94,7 @@ timeout_seconds: 5 --> ```bash -docker kill mongodb +docker kill state-store-query-mongodb ``` diff --git a/examples/validate.sh b/examples/validate.sh index 202fcaedd..6c1fdde12 100755 --- a/examples/validate.sh +++ b/examples/validate.sh @@ -1,4 +1,299 @@ #!/bin/sh echo "Home: $HOME" -cd $1 && mm.py -l README.md +run_component() { + component="$1" + cd "$component" && mm.py -l README.md +} + +extract_app_ids_from_readme() { + readme="$1" + awk ' + { + line = $0 + while (match(line, /--app-id(=|[[:space:]]+)[A-Za-z0-9._-]+/)) { + token = substr(line, RSTART, RLENGTH) + sub(/^--app-id(=|[[:space:]]+)/, "", token) + print token + line = substr(line, RSTART + RLENGTH) + } + }' "$readme" | sort -u +} + +extract_fixed_ports_from_readme() { + readme="$1" + awk ' + { + line = $0 + while (match(line, /--(app-port|dapr-http-port|dapr-grpc-port)(=|[[:space:]]+)[0-9]+/)) { + token = substr(line, RSTART, RLENGTH) + kind = token + sub(/=.*/, "", kind) + sub(/[[:space:]].*/, "", kind) + sub(/^--/, "", kind) + + port = token + sub(/^.*(=|[[:space:]]+)/, "", port) + print port "\t" kind + line = substr(line, RSTART + RLENGTH) + } + line = $0 + while (match(line, /-p[[:space:]]*[0-9]+:[0-9]+/)) { + token = substr(line, RSTART, RLENGTH) + sub(/^-p[[:space:]]*/, "", token) + split(token, parts, ":") + print parts[1] "\tdocker-host-port" + line = substr(line, RSTART + RLENGTH) + } + }' "$readme" +} + +extract_container_names_from_readme() { + readme="$1" + awk ' + { + line = $0 + while (match(line, /--name[[:space:]]+[A-Za-z0-9._-]+/)) { + token = substr(line, RSTART, RLENGTH) + sub(/^--name[[:space:]]+/, "", token) + print token + line = substr(line, RSTART + RLENGTH) + } + line = $0 + while (match(line, /docker[[:space:]]+(kill|stop|rm)[[:space:]]+[A-Za-z0-9._-]+/)) { + token = substr(line, RSTART, RLENGTH) + sub(/^docker[[:space:]]+(kill|stop|rm)[[:space:]]+/, "", token) + print token + line = substr(line, RSTART + RLENGTH) + } + }' "$readme" | sort -u +} + +assert_no_duplicate_app_ids() { + components="$1" + tmpdir="$2" + + app_ids_file="$tmpdir/app_ids.tsv" + duplicates_file="$tmpdir/duplicate_app_ids.txt" + : >"$app_ids_file" + + for component in $components; do + [ "$component" = ".." ] && continue + readme="$component/README.md" + [ -f "$readme" ] || continue + + extract_app_ids_from_readme "$readme" | while IFS= read -r app_id; do + [ -n "$app_id" ] || continue + printf '%s\t%s\n' "$app_id" "$component" >>"$app_ids_file" + done + done + + awk -F '\t' ' + { + app = $1 + component = $2 + key = app SUBSEP component + if (seen[key]++) { + next + } + count[app]++ + components[app] = (components[app] == "" ? component : components[app] ", " component) + } + END { + has_duplicates = 0 + for (app in count) { + if (count[app] > 1) { + has_duplicates = 1 + printf " - %s: %s\n", app, components[app] + } + } + exit has_duplicates ? 1 : 0 + }' "$app_ids_file" >"$duplicates_file" + + if [ $? -ne 0 ]; then + echo "Duplicate Dapr app IDs detected across examples:" + cat "$duplicates_file" + return 1 + fi + + return 0 +} + +assert_no_duplicate_fixed_ports() { + components="$1" + tmpdir="$2" + + ports_file="$tmpdir/fixed_ports.tsv" + duplicates_file="$tmpdir/duplicate_fixed_ports.txt" + : >"$ports_file" + + for component in $components; do + [ "$component" = ".." ] && continue + readme="$component/README.md" + [ -f "$readme" ] || continue + + extract_fixed_ports_from_readme "$readme" | while IFS="$(printf '\t')" read -r port kind; do + [ -n "$port" ] || continue + printf '%s\t%s\t%s\n' "$port" "$component" "$kind" >>"$ports_file" + done + done + + awk -F '\t' ' + { + port = $1 + component = $2 + kind = $3 + key = port SUBSEP component + if (seen[key]++) { + next + } + count[port]++ + details[port] = (details[port] == "" ? component " (" kind ")" : details[port] ", " component " (" kind ")") + } + END { + has_duplicates = 0 + for (port in count) { + if (count[port] > 1) { + has_duplicates = 1 + printf " - %s: %s\n", port, details[port] + } + } + exit has_duplicates ? 1 : 0 + }' "$ports_file" >"$duplicates_file" + + if [ $? -ne 0 ]; then + echo "Duplicate fixed host ports detected across examples:" + cat "$duplicates_file" + return 1 + fi + + return 0 +} + +assert_no_duplicate_container_names() { + components="$1" + tmpdir="$2" + + names_file="$tmpdir/container_names.tsv" + duplicates_file="$tmpdir/duplicate_container_names.txt" + : >"$names_file" + + for component in $components; do + [ "$component" = ".." ] && continue + readme="$component/README.md" + [ -f "$readme" ] || continue + + extract_container_names_from_readme "$readme" | while IFS= read -r name; do + [ -n "$name" ] || continue + printf '%s\t%s\n' "$name" "$component" >>"$names_file" + done + done + + awk -F '\t' ' + { + name = $1 + component = $2 + key = name SUBSEP component + if (seen[key]++) { + next + } + count[name]++ + components[name] = (components[name] == "" ? component : components[name] ", " component) + } + END { + has_duplicates = 0 + for (name in count) { + if (count[name] > 1) { + has_duplicates = 1 + printf " - %s: %s\n", name, components[name] + } + } + exit has_duplicates ? 1 : 0 + }' "$names_file" >"$duplicates_file" + + if [ $? -ne 0 ]; then + echo "Duplicate container names detected across examples:" + cat "$duplicates_file" + return 1 + fi + + return 0 +} + +run_all_components_parallel() { + tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/validate-all.XXXXXX")" || exit 1 + overall_status=0 + + components="" + for component in *; do + if [ -d "$component" ] && [ -f "$component/README.md" ]; then + components="$components $component" + fi + done + components="$components .." + + if ! assert_no_duplicate_app_ids "$components" "$tmpdir"; then + rm -rf "$tmpdir" + return 1 + fi + + if ! assert_no_duplicate_fixed_ports "$components" "$tmpdir"; then + rm -rf "$tmpdir" + return 1 + fi + + if ! assert_no_duplicate_container_names "$components" "$tmpdir"; then + rm -rf "$tmpdir" + return 1 + fi + + for component in $components; do + safe_name="$(printf '%s' "$component" | tr '/.' '__')" + ( + cd "$component" && mm.py -l README.md + ) >"$tmpdir/$safe_name.log" 2>&1 & + pid=$! + printf '%s\n' "$pid" >"$tmpdir/$safe_name.pid" + done + + for component in $components; do + safe_name="$(printf '%s' "$component" | tr '/.' '__')" + pid="$(cat "$tmpdir/$safe_name.pid")" + if wait "$pid"; then + status=0 + else + status=$? + overall_status=1 + fi + printf '%s\n' "$status" >"$tmpdir/$safe_name.status" + done + + for component in $components; do + safe_name="$(printf '%s' "$component" | tr '/.' '__')" + status="$(cat "$tmpdir/$safe_name.status")" + + if [ "$component" = ".." ]; then + label="../" + else + label="$component" + fi + + printf '===== %s =====\n' "$label" + cat "$tmpdir/$safe_name.log" + printf '\n[exit %s]\n\n' "$status" + done + + rm -rf "$tmpdir" + return "$overall_status" +} + +if [ -z "$1" ]; then + echo "Usage: $0 " >&2 + exit 2 +fi + +if [ "$1" = "all" ]; then + run_all_components_parallel +else + run_component "$1" +fi diff --git a/tox.ini b/tox.ini index 87f4bb5e9..c7ec1d879 100644 --- a/tox.ini +++ b/tox.ini @@ -45,53 +45,7 @@ deps = mechanical-markdown commands = - ./validate.sh conversation - ./validate.sh crypto - ./validate.sh metadata - ./validate.sh error_handling - ./validate.sh pubsub-simple - ./validate.sh pubsub-streaming - ./validate.sh pubsub-streaming-async - ./validate.sh state_store - ./validate.sh state_store_query - ./validate.sh secret_store - ./validate.sh invoke-simple - ./validate.sh invoke-custom-data - ./validate.sh demo_actor - ./validate.sh invoke-binding - ./validate.sh grpc_proxying - ./validate.sh w3c-tracing - ./validate.sh distributed_lock - ./validate.sh configuration - ./validate.sh demo_workflow - ./validate.sh workflow - ./validate.sh jobs - ./validate.sh langgraph-checkpointer - ./validate.sh ../ -allowlist_externals=* - -commands_pre = - pip uninstall -y dapr dapr-ext-grpc dapr-ext-fastapi dapr-ext-langgraph dapr-ext-strands dapr-ext-flask dapr-ext-langgraph dapr-ext-strands - pip install -e {toxinidir}/ \ - -e {toxinidir}/ext/dapr-ext-workflow/ \ - -e {toxinidir}/ext/dapr-ext-grpc/ \ - -e {toxinidir}/ext/dapr-ext-fastapi/ \ - -e {toxinidir}/ext/dapr-ext-langgraph/ \ - -e {toxinidir}/ext/dapr-ext-strands/ \ - -e {toxinidir}/ext/flask_dapr/ - -[testenv:example-component] -; This environment is used to validate a specific example component. -; Usage: tox -e example-component -- component_name -; Example: tox -e example-component -- conversation -passenv = HOME -basepython = python3 -changedir = ./examples/ -deps = - mechanical-markdown -commands = - ./validate.sh {posargs} - + ./validate.sh all allowlist_externals=* commands_pre =