From 7deb44321553e380009622495a558519c6e774ae Mon Sep 17 00:00:00 2001 From: Filinto Duran <1373693+filintod@users.noreply.github.com> Date: Mon, 17 Nov 2025 15:48:19 -0600 Subject: [PATCH 1/2] minimal examples test Signed-off-by: Filinto Duran <1373693+filintod@users.noreply.github.com> --- .github/workflows/pr-validation.yml | 5 +++++ examples/tests.sh | 30 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100755 examples/tests.sh diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 3ed790b..cc087cf 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -47,6 +47,11 @@ jobs: go install github.com/dapr/durabletask-go@main durabletask-go --port 4001 & tox -e py${{ matrix.python-version }}-e2e + - name: Run examples + run: | + cd examples + durabletask-go --port 4001 & + ./tests.sh publish: needs: build if: startswith(github.ref, 'refs/tags/v') diff --git a/examples/tests.sh b/examples/tests.sh new file mode 100755 index 0000000..61a3075 --- /dev/null +++ b/examples/tests.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Copyright 2025 The Dapr Authors +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -Eeuo pipefail +trap 'exit 1' ERR + +## Activity Sequence +python activity_sequence.py > activity_output +grep "Hello Tokyo!" activity_output + + +## Fan Out/Fan In +python fanout_fanin.py > fanout_fanin_output +grep "Orchestration completed! Result" fanout_fanin_output + +## Wait for Event +{ sleep 2; printf '\n'; } | python human_interaction.py --timeout 20 --approver PYTHON-CI > human_interaction_ouptput +grep "Orchestration completed! Result: \"Approved by 'PYTHON-CI'\"" human_interaction_ouptput + + From 0b1cdee1785af2e622b15254f75d4deb626b81db Mon Sep 17 00:00:00 2001 From: Filinto Duran Date: Mon, 12 Jan 2026 20:46:05 -0600 Subject: [PATCH 2/2] convert simple test to mechanical markdown Signed-off-by: Filinto Duran --- .github/workflows/pr-validation.yml | 3 +- examples/README.md | 80 ++++++++++++++++++++++++++++- examples/tests.sh | 30 ----------- 3 files changed, 80 insertions(+), 33 deletions(-) delete mode 100755 examples/tests.sh diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index cc087cf..9a697e3 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -49,9 +49,10 @@ jobs: tox -e py${{ matrix.python-version }}-e2e - name: Run examples run: | + pip install mechanical-markdown cd examples durabletask-go --port 4001 & - ./tests.sh + mm.py README.md publish: needs: build if: startswith(github.ref, 'refs/tags/v') diff --git a/examples/README.md b/examples/README.md index a6cd847..2a0eac9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -14,9 +14,34 @@ All the examples assume that you have a Durable Task-compatible sidecar running durabletask-go --port 4001 ``` -## Running the examples +## Automated Testing -With one of the sidecars running, you can simply execute any of the examples in this directory using `python3`: +These examples can be tested automatically using [mechanical-markdown](https://github.com/dapr/mechanical-markdown), which validates that the examples run correctly and produce expected output. + +To install mechanical-markdown: + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip install -e ../. +pip install mechanical-markdown +``` + +To see what commands would be run without executing them: + +```bash +mm.py -d README.md +``` + +To run all examples and validate their output: + +```bash +mm.py README.md +``` + +## Running the Examples + +With one of the sidecars running, you can execute any of the examples in this directory using `python3`: ```sh python3 ./activity_sequence.py @@ -24,6 +49,57 @@ python3 ./activity_sequence.py In some cases, the sample may require command-line parameters or user inputs. In these cases, the sample will print out instructions on how to proceed. +### Activity Sequence Example + +This example demonstrates the function chaining pattern, where an orchestrator schedules three activity calls in a sequence. + + + +```bash +python activity_sequence.py +``` + + + +### Fan-out/Fan-in Example + +This example demonstrates parallel execution, where an orchestrator schedules a dynamic number of activity calls in parallel, waits for all of them to complete, and then performs an aggregation on the results. + + + +```bash +python fanout_fanin.py +``` + + + +### Human Interaction Example + +This example demonstrates how an orchestrator can wait for external events (like human approval) with a timeout. If the approval isn't received within the specified timeout, the order is automatically cancelled. + + + +```bash +{ sleep 2; printf '\n'; } | python human_interaction.py --timeout 20 --approver PYTHON-CI +``` + + + ## List of examples - [Activity sequence](./activity_sequence.py): Orchestration that schedules three activity calls in a sequence. diff --git a/examples/tests.sh b/examples/tests.sh deleted file mode 100755 index 61a3075..0000000 --- a/examples/tests.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2025 The Dapr Authors -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -Eeuo pipefail -trap 'exit 1' ERR - -## Activity Sequence -python activity_sequence.py > activity_output -grep "Hello Tokyo!" activity_output - - -## Fan Out/Fan In -python fanout_fanin.py > fanout_fanin_output -grep "Orchestration completed! Result" fanout_fanin_output - -## Wait for Event -{ sleep 2; printf '\n'; } | python human_interaction.py --timeout 20 --approver PYTHON-CI > human_interaction_ouptput -grep "Orchestration completed! Result: \"Approved by 'PYTHON-CI'\"" human_interaction_ouptput - -