robotframework-pabot 4.3.0__tar.gz → 4.3.2__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 (46) hide show
  1. {robotframework_pabot-4.3.0/src/robotframework_pabot.egg-info → robotframework_pabot-4.3.2}/PKG-INFO +2 -2
  2. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/README.md +1 -1
  3. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/__init__.py +1 -1
  4. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/pabot.py +12 -7
  5. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2/src/robotframework_pabot.egg-info}/PKG-INFO +2 -2
  6. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_ordering.py +101 -3
  7. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/LICENSE.txt +0 -0
  8. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/MANIFEST.in +0 -0
  9. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/pyproject.toml +0 -0
  10. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/setup.cfg +0 -0
  11. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/setup.py +0 -0
  12. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/SharedLibrary.py +0 -0
  13. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/arguments.py +0 -0
  14. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/clientwrapper.py +0 -0
  15. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/coordinatorwrapper.py +0 -0
  16. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/execution_items.py +0 -0
  17. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/pabotlib.py +0 -0
  18. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/py3/__init__.py +0 -0
  19. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/py3/client.py +0 -0
  20. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/py3/coordinator.py +0 -0
  21. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/py3/messages.py +0 -0
  22. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/py3/worker.py +0 -0
  23. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/result_merger.py +0 -0
  24. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/robotremoteserver.py +0 -0
  25. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/pabot/workerwrapper.py +0 -0
  26. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/robotframework_pabot.egg-info/SOURCES.txt +0 -0
  27. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/robotframework_pabot.egg-info/dependency_links.txt +0 -0
  28. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/robotframework_pabot.egg-info/entry_points.txt +0 -0
  29. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/robotframework_pabot.egg-info/requires.txt +0 -0
  30. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/src/robotframework_pabot.egg-info/top_level.txt +0 -0
  31. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_arguments_output.py +0 -0
  32. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_basic_arguments.py +0 -0
  33. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_depends.py +0 -0
  34. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_functional.py +0 -0
  35. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_missing_subprocess_output.py +0 -0
  36. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_pabot.py +0 -0
  37. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_pabotlib.py +0 -0
  38. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_pabotprerunmodifier.py +0 -0
  39. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_pabotsuitenames_io.py +0 -0
  40. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_prerunmodifier.py +0 -0
  41. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_resultmerger.py +0 -0
  42. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_run_empty_suite.py +0 -0
  43. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_stacktrace.py +0 -0
  44. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_suite_structure.py +0 -0
  45. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_testlevelsplit_include.py +0 -0
  46. {robotframework_pabot-4.3.0 → robotframework_pabot-4.3.2}/tests/test_testlevelsplit_output_task_order.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-pabot
3
- Version: 4.3.0
3
+ Version: 4.3.2
4
4
  Summary: Parallel test runner for Robot Framework
5
5
  Home-page: https://pabot.org
6
6
  Download-URL: https://pypi.python.org/pypi/robotframework-pabot
@@ -273,7 +273,7 @@ There different possibilities to influence the execution:
273
273
  * The order of suites can be changed.
274
274
  * If a directory (or a directory structure) should be executed sequentially, add the directory suite name to a row as a ```--suite``` option.
275
275
  * 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.
276
- * You can add a line with text to force executor to wait until all previous suites have been executed.
276
+ * You can add a line with text `#WAIT` to force executor to wait until all previous suites have been executed.
277
277
  * You can group suites and tests together to same executor process by adding line `{` before the group and `}` after. Note that `#WAIT` cannot be used inside a group.
278
278
  * You can introduce dependencies using the word `#DEPENDS` after a test declaration. This keyword 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. Note that each `#WAIT` splits suites into separate execution blocks, and it's not possible to define dependencies for suites or tests that are inside another `#WAIT` block or inside another `{}` brackets.
279
279
  * Note: Within a group `{}`, neither execution order nor the `#DEPENDS` keyword currently works. This is due to limitations in Robot Framework, which is invoked within Pabot subprocesses. These limitations may be addressed in a future release of Robot Framework. For now, tests or suites within a group will be executed in the order Robot Framework discovers them — typically in alphabetical order.
@@ -247,7 +247,7 @@ There different possibilities to influence the execution:
247
247
  * The order of suites can be changed.
248
248
  * If a directory (or a directory structure) should be executed sequentially, add the directory suite name to a row as a ```--suite``` option.
249
249
  * 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.
250
- * You can add a line with text to force executor to wait until all previous suites have been executed.
250
+ * You can add a line with text `#WAIT` to force executor to wait until all previous suites have been executed.
251
251
  * You can group suites and tests together to same executor process by adding line `{` before the group and `}` after. Note that `#WAIT` cannot be used inside a group.
252
252
  * You can introduce dependencies using the word `#DEPENDS` after a test declaration. This keyword 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. Note that each `#WAIT` splits suites into separate execution blocks, and it's not possible to define dependencies for suites or tests that are inside another `#WAIT` block or inside another `{}` brackets.
253
253
  * Note: Within a group `{}`, neither execution order nor the `#DEPENDS` keyword currently works. This is due to limitations in Robot Framework, which is invoked within Pabot subprocesses. These limitations may be addressed in a future release of Robot Framework. For now, tests or suites within a group will be executed in the order Robot Framework discovers them — typically in alphabetical order.
@@ -7,4 +7,4 @@ try:
7
7
  except ImportError:
8
8
  pass
9
9
 
10
- __version__ = "4.3.0"
10
+ __version__ = "4.3.2"
@@ -2122,19 +2122,23 @@ def _parse_ordering(filename): # type: (str) -> List[ExecutionItem]
2122
2122
  raise DataError("Error parsing ordering file '%s'" % filename)
2123
2123
 
2124
2124
 
2125
+ # TODO: After issue #646, it seems necessary to thoroughly rethink how this functionality should work.
2125
2126
  def _check_ordering(ordering_file, suite_names): # type: (List[ExecutionItem], List[ExecutionItem]) -> None
2126
2127
  list_of_suite_names = [s.name for s in suite_names]
2127
- number_of_tests_or_suites = 0
2128
+ skipped_runnable_items = []
2128
2129
  if ordering_file:
2129
2130
  for item in ordering_file:
2130
2131
  if item.type in ['suite', 'test']:
2131
2132
  if not any((s == item.name or s.endswith("." + item.name)) for s in list_of_suite_names):
2132
2133
  # If test name is too long, it gets name ' Invalid', so skip that
2133
- if item.name != ' Invalid':
2134
- raise DataError("%s item '%s' in --ordering file does not match suite or test names in .pabotsuitenames file.\nPlease verify content of --ordering file." % (item.type.title(), item.name))
2135
- number_of_tests_or_suites += 1
2136
- if number_of_tests_or_suites > len(list_of_suite_names):
2137
- raise DataError('Ordering file contains more tests and/or suites than exists. Check that there is no duplicates etc. in ordering file and that to .pabotsuitenames.')
2134
+ # Additionally, the test is skipped also if the user wants a higher-level suite to be executed sequentially by using
2135
+ # the --suite option, and the given name is part of the full name of any test or suite.
2136
+ if item.name != ' Invalid' and not (item.type == 'suite' and any((s == item.name or s.startswith(item.name + ".")) for s in list_of_suite_names)):
2137
+ skipped_runnable_items.append(f"{item.type.title()} item: '{item.name}'")
2138
+ if skipped_runnable_items:
2139
+ _write("Note: The ordering file contains test or suite items that are not included in the current test run. The following items will be ignored/skipped:")
2140
+ for item in skipped_runnable_items:
2141
+ _write(f" - {item}")
2138
2142
 
2139
2143
 
2140
2144
  def _group_suites(outs_dir, datasources, options, pabot_args):
@@ -2143,7 +2147,8 @@ def _group_suites(outs_dir, datasources, options, pabot_args):
2143
2147
  ordering_arg = _parse_ordering(pabot_args.get("ordering")) if (pabot_args.get("ordering")) is not None else None
2144
2148
  if ordering_arg:
2145
2149
  _verify_depends(ordering_arg)
2146
- _check_ordering(ordering_arg, suite_names)
2150
+ # TODO: After issue #646, it seems necessary to thoroughly rethink how this functionality should work.
2151
+ #_check_ordering(ordering_arg, suite_names)
2147
2152
  ordering_arg_with_sleep = _set_sleep_times(ordering_arg)
2148
2153
  ordered_suites = _preserve_order(suite_names, ordering_arg_with_sleep)
2149
2154
  shard_suites = solve_shard_suites(ordered_suites, pabot_args)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-pabot
3
- Version: 4.3.0
3
+ Version: 4.3.2
4
4
  Summary: Parallel test runner for Robot Framework
5
5
  Home-page: https://pabot.org
6
6
  Download-URL: https://pypi.python.org/pypi/robotframework-pabot
@@ -273,7 +273,7 @@ There different possibilities to influence the execution:
273
273
  * The order of suites can be changed.
274
274
  * If a directory (or a directory structure) should be executed sequentially, add the directory suite name to a row as a ```--suite``` option.
275
275
  * 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.
276
- * You can add a line with text to force executor to wait until all previous suites have been executed.
276
+ * You can add a line with text `#WAIT` to force executor to wait until all previous suites have been executed.
277
277
  * You can group suites and tests together to same executor process by adding line `{` before the group and `}` after. Note that `#WAIT` cannot be used inside a group.
278
278
  * You can introduce dependencies using the word `#DEPENDS` after a test declaration. This keyword 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. Note that each `#WAIT` splits suites into separate execution blocks, and it's not possible to define dependencies for suites or tests that are inside another `#WAIT` block or inside another `{}` brackets.
279
279
  * Note: Within a group `{}`, neither execution order nor the `#DEPENDS` keyword currently works. This is due to limitations in Robot Framework, which is invoked within Pabot subprocesses. These limitations may be addressed in a future release of Robot Framework. For now, tests or suites within a group will be executed in the order Robot Framework discovers them — typically in alphabetical order.
@@ -34,6 +34,29 @@ class PabotOrderingGroupTest(unittest.TestCase):
34
34
  stderr=subprocess.PIPE,
35
35
  )
36
36
  return process.communicate()
37
+
38
+ def _run_tests_with_root_level_suites(self, testfiles_dict, orderfile):
39
+ for key, testfile in testfiles_dict.items():
40
+ with open("{}/{}.robot".format(self.tmpdir, key), "w") as f:
41
+ f.write(textwrap.dedent(testfile))
42
+ with open("{}/order.dat".format(self.tmpdir), "w") as f:
43
+ f.write(textwrap.dedent(orderfile))
44
+ process = subprocess.Popen(
45
+ [
46
+ sys.executable,
47
+ "-m" "pabot.pabot",
48
+ "--testlevelsplit",
49
+ "--name",
50
+ "Top Suite",
51
+ "--ordering",
52
+ "{}/order.dat".format(self.tmpdir),
53
+ "{}/".format(self.tmpdir),
54
+ ],
55
+ cwd=self.tmpdir,
56
+ stdout=subprocess.PIPE,
57
+ stderr=subprocess.PIPE,
58
+ )
59
+ return process.communicate()
37
60
 
38
61
  def test_orders(self):
39
62
  stdout, stderr = self._run_tests_with(
@@ -68,6 +91,81 @@ class PabotOrderingGroupTest(unittest.TestCase):
68
91
  self.assertNotIn(b"FAILED", stdout, stderr)
69
92
  self.assertEqual(stdout.count(b"PASSED"), 2)
70
93
 
94
+ def NOT_VALID_test_sequential_suite_execution_invalid_name(self):
95
+ stdout, stderr = self._run_tests_with(
96
+ """
97
+ *** Variables ***
98
+ ${SCALAR} Hello, globe!
99
+ *** Test Cases ***
100
+ First Test
101
+ Set Suite Variable ${SCALAR} Hello, world!
102
+ Second Test
103
+ Should Be Equal ${SCALAR} Hello, world!
104
+ Third Test
105
+ Should Be Equal ${SCALAR} Hello, world!
106
+ """,
107
+ """
108
+ --suite Invalid Name
109
+ """,
110
+ )
111
+ self.assertIn(b"Suite item 'Invalid Name' in --ordering file does not match suite or test names in .pabotsuitenames file.", stdout)
112
+ self.assertEqual(b"", stderr)
113
+
114
+ def test_multiple_suites_and_ordering_ok(self):
115
+ testfiles = {
116
+ "Suite 1":
117
+ """
118
+ *** Variables ***
119
+ ${SCALAR} Hello, globe!
120
+
121
+ *** Test Cases ***
122
+ First Test
123
+ Set Suite Variable ${SCALAR} Hello, world!
124
+
125
+ Second Test
126
+ Should Be Equal ${SCALAR} Hello, world!
127
+
128
+ Second And Quarter
129
+ Should Be Equal ${SCALAR} Hello, globe!
130
+
131
+ Second And Half
132
+ Should Be Equal ${SCALAR} Hello, globe!
133
+
134
+ Third Test
135
+ Should Be Equal ${SCALAR} Hello, globe!
136
+ """,
137
+ "Suite 2":
138
+ """
139
+ *** Variables ***
140
+ ${SCALAR} Hello, globe!
141
+ *** Test Cases ***
142
+ First Test
143
+ Set Suite Variable ${SCALAR} Hello, world!
144
+ Second Test
145
+ Should Be Equal ${SCALAR} Hello, world!
146
+ Third Test
147
+ Should Be Equal ${SCALAR} Hello, world!
148
+ """,
149
+ }
150
+ ordering_file = """
151
+ {
152
+ --test Top Suite.Suite 1.First Test
153
+ --test Top Suite.Suite 1.Second Test
154
+ }
155
+ {
156
+ --test Top Suite.Suite 1.Second And Quarter
157
+ --test Top Suite.Suite 1.Second And Half
158
+ }
159
+ --test Top Suite.Suite 1.Third Test
160
+ --suite Top Suite.Suite 2
161
+ """
162
+ stdout, stderr = self._run_tests_with_root_level_suites(testfiles, ordering_file)
163
+ self.assertIn(b"PASSED", stdout, stderr)
164
+ self.assertNotIn(b"FAILED", stdout, stderr)
165
+ self.assertEqual(stdout.count(b"PASSED"), 4)
166
+ self.assertIn(b"8 tests, 8 passed, 0 failed, 0 skipped.", stdout)
167
+ self.assertEqual(b"", stderr)
168
+
71
169
  def test_two_orders(self):
72
170
  stdout, stderr = self._run_tests_with(
73
171
  """
@@ -338,7 +436,7 @@ class PabotOrderingMalformedTest(unittest.TestCase):
338
436
  )
339
437
  return process.communicate()
340
438
 
341
- def test_ordering_file_contains_not_existing_test(self):
439
+ def NOT_VALID_test_ordering_file_contains_not_existing_test(self):
342
440
  stdout, stderr = self._run_tests_with(
343
441
  """
344
442
  *** Test Cases ***
@@ -363,7 +461,7 @@ class PabotOrderingMalformedTest(unittest.TestCase):
363
461
  )
364
462
  self.assertIn(b"Test item 'Test.Test Case E' in --ordering file does not match suite or test names in .pabotsuitenames file.", stdout, stderr)
365
463
 
366
- def test_ordering_file_contains_not_existing_default_item(self):
464
+ def NOT_VALID_test_ordering_file_contains_not_existing_default_item(self):
367
465
  # Default item is suite
368
466
  stdout, stderr = self._run_tests_with(
369
467
  """
@@ -416,7 +514,7 @@ class PabotOrderingMalformedTest(unittest.TestCase):
416
514
  )
417
515
  self.assertIn(b"Suite or test name cannot be empty and then contain #DEPENDS like: #DEPENDS Test.Test Case D", stdout, stderr)
418
516
 
419
- def test_ordering_file_contains_too_many_runnable_items(self):
517
+ def NOT_VALID_test_ordering_file_contains_too_many_runnable_items(self):
420
518
  # Default item is suite
421
519
  stdout, stderr = self._run_tests_with(
422
520
  """