Skip to content

Commit

Permalink
Merge pull request #616 from joonaskuisma/rebase_branch
Browse files Browse the repository at this point in the history
Added support for multiple #DEPENDS and introduced --pabotprerunmodifier
  • Loading branch information
mkorpela authored Jan 29, 2025
2 parents 1ba6061 + f2710fa commit c9f3dd0
Show file tree
Hide file tree
Showing 7 changed files with 460 additions and 163 deletions.
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
PabotLib.html linguist-documentation

# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto eol=lf

# These must be in LF format
tests/fixtures/** text eol=lf
tests/output.xml text eol=lf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
105 changes: 58 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,90 +53,100 @@ There are several ways you can help in improving this tool:
- Contribute by programming and making a pull request (easiest way is to work on an issue from the issue tracker)

## Command-line options

pabot [--verbose|--testlevelsplit|--command .. --end-command|
--processes num|--no-pabotlib|--pabotlibhost host|--pabotlibport port|
--processtimeout num|
--shard i/n|
--artifacts extensions|--artifactsinsubfolders|
--resourcefile file|--argumentfile[num] file|--suitesfrom file]
[robot options] [path ...]
<!-- START DOCSTRING -->
pabot [--verbose|--testlevelsplit|--command .. --end-command|
--processes num|--no-pabotlib|--pabotlibhost host|--pabotlibport port|
--processtimeout num|
--shard i/n|
--artifacts extensions|--artifactsinsubfolders|
--resourcefile file|--argumentfile[num] file|--suitesfrom file|--ordering file
--chunk
--pabotprerunmodifier modifier]
[robot options] [path ...]

PabotLib remote server is started by default to enable locking and resource distribution between parallel test executions.

Supports all [Robot Framework command line options](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#all-command-line-options) and also following pabot options:

--verbose
more output from the parallel execution
More output from the parallel execution.

--testlevelsplit
Split execution on test level instead of default suite level.
If .pabotsuitenames contains both tests and suites then this
will only affect new suites and split only them.
Leaving this flag out when both suites and tests in
.pabotsuitenames file will also only affect new suites and
add them as suite files.
Split execution on test level instead of default suite level. If .pabotsuitenames contains both tests and suites then
this will only affect new suites and split only them. Leaving this flag out when both suites and tests in
.pabotsuitenames file will also only affect new suites and add them as suite files.

--command [ACTUAL COMMANDS TO START ROBOT EXECUTOR] --end-command
RF script for situations where robot is not used directly

--processes [NUMBER OF PROCESSES]
How many parallel executors to use (default max of 2 and cpu count).
Special option "all" will use as many processes as there are
executable suites or tests.
RF script for situations where robot is not used directly.

PabotLib remote server is started by default to enable locking and resource distribution
between parallel test executions.
--processes [NUMBER OF PROCESSES]
How many parallel executors to use (default max of 2 and cpu count). Special option "all" will use as many processes as
there are executable suites or tests.

--no-pabotlib
--no-pabotlib
Disable the PabotLib remote server if you don't need locking or resource distribution features.

--pabotlibhost [HOSTNAME]
Connect to an already running instance of the PabotLib remote server at the given host
(disables the local PabotLib server start).
--pabotlibhost [HOSTNAME]
Connect to an already running instance of the PabotLib remote server at the given host (disables the local PabotLib
server start). For example, to connect to a remote PabotLib server running on another machine:

pabot --pabotlibhost 192.168.1.123 --pabotlibport 8271 tests/

The remote server can be also started and executed separately from pabot instances:

python -m pabot.pabotlib <path_to_resourcefile> <host> <port>
python -m pabot.pabotlib resource.txt 192.168.1.123 8271

This enables sharing a resource with multiple Robot Framework instances.

--pabotlibport [PORT]
Port number of the PabotLib remote server (default is 8270)
See --pabotlibhost for more information
--pabotlibport [PORT]
Port number of the PabotLib remote server (default is 8270). See --pabotlibhost for more information.

--processtimeout [TIMEOUT]
--processtimeout [TIMEOUT]
Maximum time in seconds to wait for a process before killing it. If not set, there's no timeout.

--resourcefile [FILEPATH]
Indicator for a file that can contain shared variables for distributing resources. This needs to be used together with pabotlib option. Resource file syntax is same as Windows ini files. Where a section is a shared set of variables.
--shard [INDEX]/[TOTAL]
Optionally split execution into smaller pieces. This can be used for distributing testing to multiple machines.

--artifacts [FILE EXTENSIONS]
List of file extensions (comma separated).
Defines which files (screenshots, videos etc.) from separate reporting directories would be copied and included in a final report.
Possible links to copied files in RF log would be updated (only relative paths supported).
The default value is `png`.
List of file extensions (comma separated). Defines which files (screenshots, videos etc.) from separate reporting
directories would be copied and included in a final report. Possible links to copied files in RF log would be updated
(only relative paths supported). The default value is `png`.

Examples:

--artifacts png,mp4,txt

--artifactsinsubfolders
Copy artifacts located not only directly in the RF output dir, but also in it's sub-folders.

--argumentfile[INTEGER] [FILEPATH]
--resourcefile [FILEPATH]
Indicator for a file that can contain shared variables for distributing resources. This needs to be used together with
pabotlib option. Resource file syntax is same as Windows ini files. Where a section is a shared set of variables.

--argumentfile [INTEGER] [FILEPATH]
Run same suites with multiple [argumentfile](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#argument-files) options.

For example:

--argumentfile1 arg1.txt --argumentfile2 arg2.txt

--suitesfrom [FILEPATH TO OUTPUTXML]
Optionally read suites from output.xml file. Failed suites will run
first and longer running ones will be executed before shorter ones.
--suitesfrom [FILEPATH TO OUTPUTXML]
Optionally read suites from output.xml file. Failed suites will run first and longer running ones will be executed
before shorter ones.

--ordering [FILE PATH]
Optionally give execution order from a file.

--shard [INDEX]/[TOTAL]
Optionally split execution into smaller pieces. This can
be used for distributing testing to multiple machines.
--chunk
Optionally chunk tests to PROCESSES number of robot runs. This can save time because all the suites will share the same
setups and teardowns.

--chunk
Optionally chunk tests to PROCESSES number of robot runs. This can save time because all the suites will share the same setups and teardowns.
--pabotprerunmodifier [PRERUNMODIFIER MODULE OR CLASS]
Like Robot Framework's --prerunmodifier, but executed only once in the pabot's main process after all other
--prerunmodifiers. But unlike the regular --prerunmodifier command, --pabotprerunmodifier is not executed again in each
pabot subprocesses. Depending on the intended use, this may be desirable as well as more efficient. Can be used, for
example, to modify the list of tests to be performed.

Example usages:

Expand All @@ -149,6 +159,7 @@ Example usages:
# To disable PabotLib:
pabot --no-pabotlib tests

<!-- END DOCSTRING -->
### PabotLib

pabot.PabotLib provides keywords that will help communication and data sharing between the executor processes.
Expand Down Expand Up @@ -219,7 +230,7 @@ There different possibilities to influence the execution:
* If the base suite name is changing with robot option [```--name / -N```](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#setting-the-name) you can also give partial suite name without the base suite.
* You can add a line with text `#WAIT` to force executor to wait until all previous suites have been executed.
* You can group suites and tests together to same executor process by adding line `{` before the group and `}`after.
* You can introduce dependencies using the word `#DEPENDS` after a test declaration. Please take care that in case of circular dependencies an exception will be thrown. An example could be.
* You can introduce dependencies using the word `#DEPENDS` after a test declaration. Can be used several times if it is necessary to refer to several different tests. Please take care that in case of circular dependencies an exception will be thrown. An example could be.

```
--test robotTest.1 Scalar.Test With Environment Variables #DEPENDS robotTest.1 Scalar.Test with BuiltIn Variables of Robot Framework
Expand Down
14 changes: 2 additions & 12 deletions src/pabot/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ def _parse_pabot_args(args): # type: (List[str]) -> Tuple[List[str], Dict[str,
"resourcefile": str,
"pabotlibhost": str,
"pabotlibport": int,
"pabotprerunmodifier": str,
"processtimeout": int,
"ordering": _parse_ordering,
"ordering": str,
"suitesfrom": str,
"artifacts": lambda x: x.split(","),
"shard": _parse_shard,
Expand Down Expand Up @@ -195,17 +196,6 @@ def _parse_pabot_args(args): # type: (List[str]) -> Tuple[List[str], Dict[str,
return remaining_args, pabot_args


def _parse_ordering(filename): # type: (str) -> List[ExecutionItem]
try:
with open(filename, "r") as orderingfile:
return [
parse_execution_item_line(line.strip())
for line in orderingfile.readlines()
]
except:
raise DataError("Error parsing ordering file '%s'" % filename)


def _delete_none_keys(d): # type: (Dict[str, Optional[object]]) -> Dict[str, object]
keys = set()
for k in d:
Expand Down
26 changes: 19 additions & 7 deletions src/pabot/execution_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from robot.errors import DataError
from robot.utils import PY2, is_unicode

import re

@total_ordering
class ExecutionItem(object):
Expand Down Expand Up @@ -97,28 +98,39 @@ def modify_options_for_executor(self, options):
class RunnableItem(ExecutionItem):
pass

depends = None # type: str
depends = None # type: List[str]
depends_keyword = "#DEPENDS"

def _split_dependencies(self, line_name, depends_indexes):
depends_lst = [] if len(depends_indexes) < 2 else [line_name[i + len(self.depends_keyword) : j].strip() for i, j in zip(depends_indexes, depends_indexes[1:])]
depends_lst.append(line_name[depends_indexes[-1] + len(self.depends_keyword) : ].strip())
return depends_lst

def _merge_dependencies(self, line_start):
output_line = line_start
for d in self.depends:
output_line = output_line + " " + self.depends_keyword + " " + d
return output_line

def set_name_and_depends(self, name):
line_name = name.encode("utf-8") if PY2 and is_unicode(name) else name
depends_begin_index = line_name.find(self.depends_keyword)
depends_indexes = [d.start() for d in re.finditer(self.depends_keyword, line_name)]
self.name = (
line_name
if depends_begin_index == -1
else line_name[0:depends_begin_index].strip()
if len(depends_indexes) == 0
else line_name[0:depends_indexes[0]].strip()
)
self.depends = (
line_name[depends_begin_index + len(self.depends_keyword) :].strip()
if depends_begin_index != -1
self._split_dependencies(line_name, depends_indexes)
if len(depends_indexes) != 0
else None
)

def line(self):
# type: () -> str
line_without_depends = "--" + self.type + " " + self.name
return (
line_without_depends + " " + self.depends_keyword + " " + self.depends
self._merge_dependencies(line_without_depends)
if self.depends
else line_without_depends
)
Expand Down
Loading

0 comments on commit c9f3dd0

Please sign in to comment.