robotframework-pabot 2.14.0__tar.gz → 2.16.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.
Files changed (29) hide show
  1. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/PKG-INFO +1 -1
  2. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/README.md +4 -0
  3. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/__init__.py +1 -1
  4. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/arguments.py +6 -0
  5. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/pabot.py +33 -7
  6. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/result_merger.py +1 -1
  7. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/PKG-INFO +1 -1
  8. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/LICENSE.txt +0 -0
  9. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/MANIFEST.in +0 -0
  10. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/pyproject.toml +0 -0
  11. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/setup.cfg +0 -0
  12. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/setup.py +0 -0
  13. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/SharedLibrary.py +0 -0
  14. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/clientwrapper.py +0 -0
  15. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/coordinatorwrapper.py +0 -0
  16. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/execution_items.py +0 -0
  17. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/pabotlib.py +0 -0
  18. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/py3/__init__.py +0 -0
  19. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/py3/client.py +0 -0
  20. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/py3/coordinator.py +0 -0
  21. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/py3/messages.py +0 -0
  22. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/py3/worker.py +0 -0
  23. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/robotremoteserver.py +0 -0
  24. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/pabot/workerwrapper.py +0 -0
  25. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/SOURCES.txt +0 -0
  26. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/dependency_links.txt +0 -0
  27. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/entry_points.txt +0 -0
  28. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/requires.txt +0 -0
  29. {robotframework-pabot-2.14.0 → robotframework-pabot-2.16.0}/src/robotframework_pabot.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotframework-pabot
3
- Version: 2.14.0
3
+ Version: 2.16.0
4
4
  Summary: Parallel test runner for Robot Framework
5
5
  Home-page: https://pabot.org
6
6
  Author: Mikko Korpela
@@ -57,6 +57,7 @@ There are several ways you can help in improving this tool:
57
57
 
58
58
  pabot [--verbose|--testlevelsplit|--command .. --end-command|
59
59
  --processes num|--pabotlib|--pabotlibhost host|--pabotlibport port|
60
+ --processtimeout num|
60
61
  --shard i/n|
61
62
  --artifacts extensions|--artifactsinsubfolders|
62
63
  --resourcefile file|--argumentfile[num] file|--suitesfrom file]
@@ -100,6 +101,9 @@ Supports all [Robot Framework command line options](https://robotframework.org/r
100
101
  Port number of the PabotLib remote server (default is 8270)
101
102
  See --pabotlibhost for more information
102
103
 
104
+ --processtimeout [TIMEOUT]
105
+ Maximum time in seconds to wait for a process before killing it. If not set, there's no timeout.
106
+
103
107
  --resourcefile [FILEPATH]
104
108
  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.
105
109
 
@@ -1,4 +1,4 @@
1
1
  from __future__ import absolute_import
2
2
 
3
3
  from .pabotlib import PabotLib
4
- __version__ = "2.14.0"
4
+ __version__ = "2.16.0"
@@ -72,6 +72,7 @@ def _parse_pabot_args(args): # type: (List[str]) -> Tuple[List[str], Dict[str,
72
72
  "pabotlibhost": "127.0.0.1",
73
73
  "pabotlibport": 8270,
74
74
  "processes": _processes_count(),
75
+ "processtimeout": None,
75
76
  "artifacts": ["png"],
76
77
  "artifactsinsubfolders": False,
77
78
  "shardindex": 0,
@@ -93,6 +94,7 @@ def _parse_pabot_args(args): # type: (List[str]) -> Tuple[List[str], Dict[str,
93
94
  "pabotlib",
94
95
  "pabotlibhost",
95
96
  "pabotlibport",
97
+ "processtimeout",
96
98
  "ordering",
97
99
  "suitesfrom",
98
100
  "artifacts",
@@ -149,6 +151,10 @@ def _parse_pabot_args(args): # type: (List[str]) -> Tuple[List[str], Dict[str,
149
151
  pabot_args["pabotlibport"] = int(args[1])
150
152
  args = args[2:]
151
153
  continue
154
+ if args[0] == "--processtimeout":
155
+ pabot_args["processtimeout"] = int(args[1])
156
+ args = args[2:]
157
+ continue
152
158
  if args[0] == "--suitesfrom":
153
159
  pabot_args["suitesfrom"] = args[1]
154
160
  args = args[2:]
@@ -54,6 +54,9 @@ options (these must be before normal RF options):
54
54
  --pabotlibport [PORT]
55
55
  Port number of the PabotLib remote server (default is 8270)
56
56
 
57
+ --processtimeout [TIMEOUT]
58
+ Maximum time in seconds to wait for a process before killing it. If not set, there's no timeout.
59
+
57
60
  --ordering [FILE PATH]
58
61
  Optionally give execution order from a file.
59
62
 
@@ -229,6 +232,7 @@ def execute_and_wait_with(item):
229
232
  caller_id,
230
233
  item.index,
231
234
  item.execution_item.type != "test",
235
+ process_timeout=item.timeout
232
236
  )
233
237
  outputxml_preprocessing(
234
238
  item.options, outs_dir, name, item.verbose, _make_id(), caller_id
@@ -286,8 +290,9 @@ def _try_execute_and_wait(
286
290
  caller_id,
287
291
  my_index=-1,
288
292
  show_stdout_on_failure=False,
293
+ process_timeout=None
289
294
  ):
290
- # type: (List[str], str, str, bool, int, str, int, bool) -> None
295
+ # type: (List[str], str, str, bool, int, str, int, bool, Optional[int]) -> None
291
296
  plib = None
292
297
  is_ignored = False
293
298
  if _pabotlib_in_use():
@@ -296,7 +301,7 @@ def _try_execute_and_wait(
296
301
  with open(os.path.join(outs_dir, cmd[0] + "_stdout.out"), "w") as stdout:
297
302
  with open(os.path.join(outs_dir, cmd[0] + "_stderr.out"), "w") as stderr:
298
303
  process, (rc, elapsed) = _run(
299
- cmd, stderr, stdout, item_name, verbose, pool_id, my_index, outs_dir
304
+ cmd, stderr, stdout, item_name, verbose, pool_id, my_index, outs_dir, process_timeout
300
305
  )
301
306
  except:
302
307
  _write(traceback.format_exc())
@@ -469,8 +474,8 @@ def _increase_completed(plib, my_index):
469
474
  )
470
475
 
471
476
 
472
- def _run(command, stderr, stdout, item_name, verbose, pool_id, item_index, outs_dir):
473
- # type: (List[str], IO[Any], IO[Any], str, bool, int, int, str) -> Tuple[Union[subprocess.Popen[bytes], subprocess.Popen], Tuple[int, float]]
477
+ def _run(command, stderr, stdout, item_name, verbose, pool_id, item_index, outs_dir, process_timeout):
478
+ # type: (List[str], IO[Any], IO[Any], str, bool, int, int, str, Optional[int]) -> Tuple[Union[subprocess.Popen[bytes], subprocess.Popen], Tuple[int, float]]
474
479
  timestamp = datetime.datetime.now()
475
480
  cmd = " ".join(command)
476
481
  if PY2:
@@ -498,10 +503,10 @@ def _run(command, stderr, stdout, item_name, verbose, pool_id, item_index, outs_
498
503
  "EXECUTING %s" % item_name,
499
504
  timestamp=timestamp,
500
505
  )
501
- return process, _wait_for_return_code(process, item_name, pool_id, item_index)
506
+ return process, _wait_for_return_code(process, item_name, pool_id, item_index, process_timeout)
502
507
 
503
508
 
504
- def _wait_for_return_code(process, item_name, pool_id, item_index):
509
+ def _wait_for_return_code(process, item_name, pool_id, item_index, process_timeout):
505
510
  rc = None
506
511
  elapsed = 0
507
512
  ping_time = ping_interval = 150
@@ -509,6 +514,19 @@ def _wait_for_return_code(process, item_name, pool_id, item_index):
509
514
  rc = process.poll()
510
515
  time.sleep(0.1)
511
516
  elapsed += 1
517
+
518
+ if process_timeout and elapsed / 10.0 >= process_timeout:
519
+ process.terminate()
520
+ process.wait()
521
+ rc = -1 # Set a return code indicating that the process was killed due to timeout
522
+ _write_with_id(
523
+ process,
524
+ pool_id,
525
+ item_index,
526
+ "Process %s killed due to exceeding the maximum timeout of %s seconds" % (item_name, process_timeout),
527
+ )
528
+ break
529
+
512
530
  if elapsed == ping_time:
513
531
  ping_interval += 50
514
532
  ping_time += ping_interval
@@ -518,9 +536,11 @@ def _wait_for_return_code(process, item_name, pool_id, item_index):
518
536
  item_index,
519
537
  "still running %s after %s seconds" % (item_name, elapsed / 10.0),
520
538
  )
539
+
521
540
  return rc, elapsed / 10.0
522
541
 
523
542
 
543
+
524
544
  def _read_file(file_handle):
525
545
  try:
526
546
  with open(file_handle.name, "r") as content_file:
@@ -1238,6 +1258,7 @@ def _options_for_rebot(options, start_time_string, end_time_string):
1238
1258
  "maxassignlength",
1239
1259
  "maxerrorlines",
1240
1260
  "monitorcolors",
1261
+ "parser",
1241
1262
  "prerunmodifier",
1242
1263
  "quiet",
1243
1264
  "randomize",
@@ -1617,8 +1638,9 @@ class QueueItem(object):
1617
1638
  argfile,
1618
1639
  hive=None,
1619
1640
  processes=0,
1641
+ timeout=None
1620
1642
  ):
1621
- # type: (List[str], str, Dict[str, object], ExecutionItem, List[str], bool, Tuple[str, Optional[str]], Optional[str], int) -> None
1643
+ # type: (List[str], str, Dict[str, object], ExecutionItem, List[str], bool, Tuple[str, Optional[str]], Optional[str], int, Optional[int]) -> None
1622
1644
  self.datasources = datasources
1623
1645
  self.outs_dir = (
1624
1646
  outs_dir.encode("utf-8") if PY2 and is_unicode(outs_dir) else outs_dir
@@ -1636,6 +1658,7 @@ class QueueItem(object):
1636
1658
  self.last_level = None
1637
1659
  self.hive = hive
1638
1660
  self.processes = processes
1661
+ self.timeout = timeout
1639
1662
 
1640
1663
  @property
1641
1664
  def index(self):
@@ -1713,6 +1736,7 @@ def _create_items(datasources, opts_for_run, outs_dir, pabot_args, suite_group):
1713
1736
  argfile,
1714
1737
  pabot_args.get("hive"),
1715
1738
  pabot_args["processes"],
1739
+ pabot_args["processtimeout"]
1716
1740
  )
1717
1741
  for suite in suite_group
1718
1742
  for argfile in pabot_args["argumentfiles"] or [("", None)]
@@ -1757,6 +1781,7 @@ def _chunk_items(items, chunk_size):
1757
1781
  base_item.verbose,
1758
1782
  (base_item.argfile_index, base_item.argfile),
1759
1783
  processes=base_item.processes,
1784
+ timeout=base_item.timeout
1760
1785
  )
1761
1786
  yield chunked_item
1762
1787
 
@@ -1836,6 +1861,7 @@ def _get_dynamically_created_execution_items(
1836
1861
  ("", None),
1837
1862
  pabot_args.get("hive"),
1838
1863
  pabot_args["processes"],
1864
+ pabot_args["processtimeout"]
1839
1865
  )
1840
1866
  for suite in suite_group
1841
1867
  ]
@@ -56,7 +56,7 @@ class ResultMerger(SuiteVisitor):
56
56
  try:
57
57
  self._set_prefix(merged.source)
58
58
  merged.suite.visit(self)
59
- self.root.metadata._add_initial(merged.suite.metadata)
59
+ self.root.metadata.update(merged.suite.metadata)
60
60
  if self.errors != merged.errors:
61
61
  self.errors.add(merged.errors)
62
62
  except:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotframework-pabot
3
- Version: 2.14.0
3
+ Version: 2.16.0
4
4
  Summary: Parallel test runner for Robot Framework
5
5
  Home-page: https://pabot.org
6
6
  Author: Mikko Korpela