robotframework-parallelrunner 0.3.1__tar.gz → 0.5.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.
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/PKG-INFO +39 -19
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/README.md +37 -16
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/pyproject.toml +2 -3
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/src/ParallelRunner/__init__.py +2 -2
- robotframework_parallelrunner-0.5.0/src/ParallelRunner/parallel_library.py +1083 -0
- robotframework_parallelrunner-0.5.0/src/ParallelRunner/retry.py +114 -0
- robotframework_parallelrunner-0.3.1/src/ParallelRunner/parallel_library.py +0 -566
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/LICENSE +0 -0
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/src/ParallelRunner/py.typed +0 -0
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/src/ParallelRunner/version.py +0 -0
- {robotframework_parallelrunner-0.3.1 → robotframework_parallelrunner-0.5.0}/src/parallelrunner.py +0 -0
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: robotframework-parallelrunner
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Run a keyword in parallel inside a single Robot Framework test case, with one clean, ordered log.html.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: robotframework,robot-framework,parallel,threading,testing,automation
|
|
8
8
|
Author: Cristian Garcia
|
|
9
9
|
Author-email: cristian.garcia.vd@gmail.com
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Framework :: Robot Framework
|
|
13
13
|
Classifier: Framework :: Robot Framework :: Library
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -53,9 +52,10 @@ correctly ordered `log.html` plus a structured list of per-item results.
|
|
|
53
52
|
pip install robotframework-parallelrunner
|
|
54
53
|
```
|
|
55
54
|
|
|
56
|
-
Requires Python 3.
|
|
57
|
-
See [docs/INSTALLATION.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/docs/INSTALLATION.md) for development installs
|
|
58
|
-
|
|
55
|
+
Requires Python 3.10+ and Robot Framework 5.0+ (installed automatically).
|
|
56
|
+
See [docs/INSTALLATION.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/docs/INSTALLATION.md) for development installs,
|
|
57
|
+
upgrading from the pre-release import path, and Python 3.8/3.9 (no longer
|
|
58
|
+
supported, but 0.5.0 was tested and works on them).
|
|
59
59
|
|
|
60
60
|
## Quickstart
|
|
61
61
|
|
|
@@ -113,8 +113,8 @@ threading, buffering, and replay logic stay out of your `.robot` files.
|
|
|
113
113
|
## Summary of Benefits
|
|
114
114
|
|
|
115
115
|
- **Speed.** Waiting time is overlapped instead of added up. In this repo's
|
|
116
|
-
examples, 9 HTTP checks with a 1 s delay each drop from 13 s to 2 s with
|
|
117
|
-
9 workers, and 4 suites × 8 items × 1 s drop from 32.
|
|
116
|
+
examples, 9 HTTP checks with a 1 s delay each drop from 13.9 s to 2.2 s with
|
|
117
|
+
9 workers, and 4 suites × 8 items × 1 s drop from 32.9 s to 5.1 s with
|
|
118
118
|
8 workers (see [Using It Together With pabot](#using-it-together-with-pabot)).
|
|
119
119
|
- **Integrity.** Your `log.html` remains the single source of truth — no
|
|
120
120
|
broken XML tags from concurrent writes.
|
|
@@ -183,7 +183,7 @@ pabot --processes 4 --pythonpath . atest/
|
|
|
183
183
|
pabot --processes 4 --testlevelsplit --pythonpath . atest/
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
Both commands pass the full acceptance suite of this repository (
|
|
186
|
+
Both commands pass the full acceptance suite of this repository (82 tests;
|
|
187
187
|
checked with pabot 5.2.2).
|
|
188
188
|
|
|
189
189
|
How much time each one saves, from the offline
|
|
@@ -192,14 +192,14 @@ How much time each one saves, from the offline
|
|
|
192
192
|
|
|
193
193
|
| Run | Wall-clock time | Speedup |
|
|
194
194
|
|---|---|---|
|
|
195
|
-
| robot, sequential loop | 32.
|
|
196
|
-
| robot + ParallelRunner (8 workers) |
|
|
197
|
-
| pabot (4 processes), sequential loop |
|
|
198
|
-
| pabot (4 processes) + ParallelRunner (8 workers) |
|
|
195
|
+
| robot, sequential loop | 32.9 s | ×1.0 |
|
|
196
|
+
| robot + ParallelRunner (8 workers) | 5.1 s | ×6.5 |
|
|
197
|
+
| pabot (4 processes), sequential loop | 12.4 s | ×2.7 |
|
|
198
|
+
| pabot (4 processes) + ParallelRunner (8 workers) | 4.6 s | ×7.2 |
|
|
199
199
|
|
|
200
200
|
ParallelRunner removes the waiting *inside* each test, and pabot removes it
|
|
201
201
|
*between* suites. With suites this short, pabot's process start-up (about
|
|
202
|
-
|
|
202
|
+
3.5 s here) is most of what's left, so the combination pays off more as
|
|
203
203
|
suites get longer.
|
|
204
204
|
|
|
205
205
|
Things to keep in mind:
|
|
@@ -221,6 +221,31 @@ Things to keep in mind:
|
|
|
221
221
|
could interfere with each other. Keep shared state per process, or split
|
|
222
222
|
by suite.
|
|
223
223
|
|
|
224
|
+
## How Is This Different From AsyncLibrary?
|
|
225
|
+
|
|
226
|
+
[AsyncLibrary](https://github.com/rlehfeld/robotframework-async-keyword)
|
|
227
|
+
(`pip install robotframework-async-keyword`) also runs keywords in threads
|
|
228
|
+
inside one test case. It runs *any* keyword, user keywords included: you
|
|
229
|
+
start each call with `Async Run` and collect it later with `Async Get`. It
|
|
230
|
+
buffers each call's output and replays it, so `log.html` keeps the full
|
|
231
|
+
nested keyword structure. To do that, it works with Robot Framework's
|
|
232
|
+
internal execution context and output.
|
|
233
|
+
|
|
234
|
+
| | **AsyncLibrary** | **ParallelRunner** |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| Runs | Any keyword, including user keywords | A method of a Python library that accepts `_logger` |
|
|
237
|
+
| Usage | `Async Run` per call, `Async Get` later | One `Run Parallel Scenarios` call over a list, or `repeat=N` |
|
|
238
|
+
| Concurrency | Python's default thread pool size | `ROBOT_THREAD_WORKERS` |
|
|
239
|
+
| Hung calls | `Async Get timeout=...` stops waiting for them | `call_timeout` fails only that call and frees its slot for the next item |
|
|
240
|
+
| Failures | `Async Get` raises the call's error | One failure listing every failed item, or a `PASS`/`FAIL` per item with `fail_on_error=False` |
|
|
241
|
+
| Robot internals | Works with the internal execution context and output | Not patched; logs only from the main thread, through the public logger API; tested on Robot Framework 5, 6 and 7 |
|
|
242
|
+
|
|
243
|
+
Use AsyncLibrary when the work lives in user keywords (or in library
|
|
244
|
+
keywords you can't change), or when you want to start something in the
|
|
245
|
+
background, run other steps, and collect it later. Use ParallelRunner to fan
|
|
246
|
+
one Python keyword out over many items as a single batch, with a bounded
|
|
247
|
+
worker pool, per-call timeouts and one failure report for the whole batch.
|
|
248
|
+
|
|
224
249
|
## When Not To Use This
|
|
225
250
|
|
|
226
251
|
- **CPU-bound work.** Threads share Python's GIL — number crunching won't
|
|
@@ -230,11 +255,6 @@ Things to keep in mind:
|
|
|
230
255
|
made thread-safe for you; your own keyword's side effects are not. If it
|
|
231
256
|
writes to a shared variable, file, or object without a lock, running it
|
|
232
257
|
concurrently can race the same way any multi-threaded code can.
|
|
233
|
-
- **You need per-item retries or a per-item timeout.** Not implemented yet
|
|
234
|
-
(see [ROADMAP.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/ROADMAP.md)). A Robot `[Timeout]` on the test or keyword does
|
|
235
|
-
interrupt the whole batch when it expires and replays the logs collected so
|
|
236
|
-
far, but calls that are already running can't be stopped: they keep running
|
|
237
|
-
in the background until they return.
|
|
238
258
|
- **You need process-level isolation** (a crash in one call shouldn't be
|
|
239
259
|
able to affect another) or cross-machine parallelism — that's pabot's
|
|
240
260
|
domain, not this library's.
|
|
@@ -19,9 +19,10 @@ correctly ordered `log.html` plus a structured list of per-item results.
|
|
|
19
19
|
pip install robotframework-parallelrunner
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Requires Python 3.
|
|
23
|
-
See [docs/INSTALLATION.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/docs/INSTALLATION.md) for development installs
|
|
24
|
-
|
|
22
|
+
Requires Python 3.10+ and Robot Framework 5.0+ (installed automatically).
|
|
23
|
+
See [docs/INSTALLATION.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/docs/INSTALLATION.md) for development installs,
|
|
24
|
+
upgrading from the pre-release import path, and Python 3.8/3.9 (no longer
|
|
25
|
+
supported, but 0.5.0 was tested and works on them).
|
|
25
26
|
|
|
26
27
|
## Quickstart
|
|
27
28
|
|
|
@@ -79,8 +80,8 @@ threading, buffering, and replay logic stay out of your `.robot` files.
|
|
|
79
80
|
## Summary of Benefits
|
|
80
81
|
|
|
81
82
|
- **Speed.** Waiting time is overlapped instead of added up. In this repo's
|
|
82
|
-
examples, 9 HTTP checks with a 1 s delay each drop from 13 s to 2 s with
|
|
83
|
-
9 workers, and 4 suites × 8 items × 1 s drop from 32.
|
|
83
|
+
examples, 9 HTTP checks with a 1 s delay each drop from 13.9 s to 2.2 s with
|
|
84
|
+
9 workers, and 4 suites × 8 items × 1 s drop from 32.9 s to 5.1 s with
|
|
84
85
|
8 workers (see [Using It Together With pabot](#using-it-together-with-pabot)).
|
|
85
86
|
- **Integrity.** Your `log.html` remains the single source of truth — no
|
|
86
87
|
broken XML tags from concurrent writes.
|
|
@@ -149,7 +150,7 @@ pabot --processes 4 --pythonpath . atest/
|
|
|
149
150
|
pabot --processes 4 --testlevelsplit --pythonpath . atest/
|
|
150
151
|
```
|
|
151
152
|
|
|
152
|
-
Both commands pass the full acceptance suite of this repository (
|
|
153
|
+
Both commands pass the full acceptance suite of this repository (82 tests;
|
|
153
154
|
checked with pabot 5.2.2).
|
|
154
155
|
|
|
155
156
|
How much time each one saves, from the offline
|
|
@@ -158,14 +159,14 @@ How much time each one saves, from the offline
|
|
|
158
159
|
|
|
159
160
|
| Run | Wall-clock time | Speedup |
|
|
160
161
|
|---|---|---|
|
|
161
|
-
| robot, sequential loop | 32.
|
|
162
|
-
| robot + ParallelRunner (8 workers) |
|
|
163
|
-
| pabot (4 processes), sequential loop |
|
|
164
|
-
| pabot (4 processes) + ParallelRunner (8 workers) |
|
|
162
|
+
| robot, sequential loop | 32.9 s | ×1.0 |
|
|
163
|
+
| robot + ParallelRunner (8 workers) | 5.1 s | ×6.5 |
|
|
164
|
+
| pabot (4 processes), sequential loop | 12.4 s | ×2.7 |
|
|
165
|
+
| pabot (4 processes) + ParallelRunner (8 workers) | 4.6 s | ×7.2 |
|
|
165
166
|
|
|
166
167
|
ParallelRunner removes the waiting *inside* each test, and pabot removes it
|
|
167
168
|
*between* suites. With suites this short, pabot's process start-up (about
|
|
168
|
-
|
|
169
|
+
3.5 s here) is most of what's left, so the combination pays off more as
|
|
169
170
|
suites get longer.
|
|
170
171
|
|
|
171
172
|
Things to keep in mind:
|
|
@@ -187,6 +188,31 @@ Things to keep in mind:
|
|
|
187
188
|
could interfere with each other. Keep shared state per process, or split
|
|
188
189
|
by suite.
|
|
189
190
|
|
|
191
|
+
## How Is This Different From AsyncLibrary?
|
|
192
|
+
|
|
193
|
+
[AsyncLibrary](https://github.com/rlehfeld/robotframework-async-keyword)
|
|
194
|
+
(`pip install robotframework-async-keyword`) also runs keywords in threads
|
|
195
|
+
inside one test case. It runs *any* keyword, user keywords included: you
|
|
196
|
+
start each call with `Async Run` and collect it later with `Async Get`. It
|
|
197
|
+
buffers each call's output and replays it, so `log.html` keeps the full
|
|
198
|
+
nested keyword structure. To do that, it works with Robot Framework's
|
|
199
|
+
internal execution context and output.
|
|
200
|
+
|
|
201
|
+
| | **AsyncLibrary** | **ParallelRunner** |
|
|
202
|
+
|---|---|---|
|
|
203
|
+
| Runs | Any keyword, including user keywords | A method of a Python library that accepts `_logger` |
|
|
204
|
+
| Usage | `Async Run` per call, `Async Get` later | One `Run Parallel Scenarios` call over a list, or `repeat=N` |
|
|
205
|
+
| Concurrency | Python's default thread pool size | `ROBOT_THREAD_WORKERS` |
|
|
206
|
+
| Hung calls | `Async Get timeout=...` stops waiting for them | `call_timeout` fails only that call and frees its slot for the next item |
|
|
207
|
+
| Failures | `Async Get` raises the call's error | One failure listing every failed item, or a `PASS`/`FAIL` per item with `fail_on_error=False` |
|
|
208
|
+
| Robot internals | Works with the internal execution context and output | Not patched; logs only from the main thread, through the public logger API; tested on Robot Framework 5, 6 and 7 |
|
|
209
|
+
|
|
210
|
+
Use AsyncLibrary when the work lives in user keywords (or in library
|
|
211
|
+
keywords you can't change), or when you want to start something in the
|
|
212
|
+
background, run other steps, and collect it later. Use ParallelRunner to fan
|
|
213
|
+
one Python keyword out over many items as a single batch, with a bounded
|
|
214
|
+
worker pool, per-call timeouts and one failure report for the whole batch.
|
|
215
|
+
|
|
190
216
|
## When Not To Use This
|
|
191
217
|
|
|
192
218
|
- **CPU-bound work.** Threads share Python's GIL — number crunching won't
|
|
@@ -196,11 +222,6 @@ Things to keep in mind:
|
|
|
196
222
|
made thread-safe for you; your own keyword's side effects are not. If it
|
|
197
223
|
writes to a shared variable, file, or object without a lock, running it
|
|
198
224
|
concurrently can race the same way any multi-threaded code can.
|
|
199
|
-
- **You need per-item retries or a per-item timeout.** Not implemented yet
|
|
200
|
-
(see [ROADMAP.md](https://github.com/cristiangarciavd/robotframework-parallelrunner/blob/main/ROADMAP.md)). A Robot `[Timeout]` on the test or keyword does
|
|
201
|
-
interrupt the whole batch when it expires and replays the logs collected so
|
|
202
|
-
far, but calls that are already running can't be stopped: they keep running
|
|
203
|
-
in the background until they return.
|
|
204
225
|
- **You need process-level isolation** (a crash in one call shouldn't be
|
|
205
226
|
able to affect another) or cross-machine parallelism — that's pabot's
|
|
206
227
|
domain, not this library's.
|
|
@@ -6,12 +6,12 @@ build-backend = "poetry.core.masonry.api"
|
|
|
6
6
|
name = "robotframework-parallelrunner"
|
|
7
7
|
# Single source of truth for the version: bump with `poetry version patch|minor|major`.
|
|
8
8
|
# ParallelRunner.__version__ / ROBOT_LIBRARY_VERSION read it back from the installed metadata.
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.5.0"
|
|
10
10
|
description = "Run a keyword in parallel inside a single Robot Framework test case, with one clean, ordered log.html."
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
license = "MIT"
|
|
13
13
|
license-files = ["LICENSE"]
|
|
14
|
-
requires-python = ">=3.
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
15
|
authors = [
|
|
16
16
|
{ name = "Cristian Garcia", email = "cristian.garcia.vd@gmail.com" },
|
|
17
17
|
]
|
|
@@ -30,7 +30,6 @@ classifiers = [
|
|
|
30
30
|
"Intended Audience :: Developers",
|
|
31
31
|
"Operating System :: OS Independent",
|
|
32
32
|
"Programming Language :: Python :: 3",
|
|
33
|
-
"Programming Language :: Python :: 3.9",
|
|
34
33
|
"Programming Language :: Python :: 3.10",
|
|
35
34
|
"Programming Language :: Python :: 3.11",
|
|
36
35
|
"Programming Language :: Python :: 3.12",
|
|
@@ -13,7 +13,7 @@ Keyword documentation:
|
|
|
13
13
|
https://cristiangarciavd.github.io/robotframework-parallelrunner/ParallelRunner.html
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
from .parallel_library import ParallelLibrary, ParallelRunner, ParallelTaskError
|
|
16
|
+
from .parallel_library import ParallelLibrary, ParallelRunner, ParallelTaskError, log_to_robot
|
|
17
17
|
from .version import __version__
|
|
18
18
|
|
|
19
|
-
__all__ = ["ParallelRunner", "ParallelLibrary", "ParallelTaskError", "__version__"]
|
|
19
|
+
__all__ = ["ParallelRunner", "ParallelLibrary", "ParallelTaskError", "log_to_robot", "__version__"]
|