pybuilder-integration 104__tar.gz → 106__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 (20) hide show
  1. {pybuilder_integration-104 → pybuilder_integration-106}/PKG-INFO +4 -3
  2. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/artifact_manager.py +9 -1
  3. pybuilder_integration-106/pybuilder_integration/directory_utility.py +168 -0
  4. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/properties.py +1 -0
  5. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/tasks.py +82 -16
  6. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/PKG-INFO +4 -3
  7. pybuilder_integration-106/pybuilder_integration.egg-info/requires.txt +4 -0
  8. {pybuilder_integration-104 → pybuilder_integration-106}/setup.py +4 -3
  9. pybuilder_integration-104/pybuilder_integration/directory_utility.py +0 -70
  10. pybuilder_integration-104/pybuilder_integration.egg-info/requires.txt +0 -3
  11. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/__init__.py +0 -0
  12. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/cloudwatchlogs_utility.py +0 -0
  13. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/exec_utility.py +0 -0
  14. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration/tool_utility.py +0 -0
  15. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/SOURCES.txt +0 -0
  16. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/dependency_links.txt +0 -0
  17. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/namespace_packages.txt +0 -0
  18. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/top_level.txt +0 -0
  19. {pybuilder_integration-104 → pybuilder_integration-106}/pybuilder_integration.egg-info/zip-safe +0 -0
  20. {pybuilder_integration-104 → pybuilder_integration-106}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybuilder-integration
3
- Version: 104
3
+ Version: 106
4
4
  Summary: A pybuilder plugin that runs integration tests (Tavern & Cypress) against a target.
5
5
  Home-page: https://github.com/rspitler/pybuilder-integration
6
6
  Author:
@@ -10,9 +10,10 @@ Maintainer-email:
10
10
  License: Apache 2.0
11
11
  Classifier: Development Status :: 3 - Alpha
12
12
  Classifier: Programming Language :: Python
13
- Requires-Dist: pytest
13
+ Requires-Dist: pytest==7.4.4
14
14
  Requires-Dist: tavern==1.25.2
15
- Requires-Dist: boto3
15
+ Requires-Dist: boto3==1.43.72
16
+ Requires-Dist: defusedxml==0.7.1
16
17
  Dynamic: classifier
17
18
  Dynamic: description
18
19
  Dynamic: home-page
@@ -8,7 +8,7 @@ from pybuilder.reactor import Reactor
8
8
 
9
9
  from pybuilder_integration import exec_utility
10
10
  from pybuilder_integration.directory_utility import get_latest_distribution_directory, \
11
- get_latest_zipped_distribution_directory
11
+ get_latest_zipped_distribution_directory, read_tavern_service_markers, write_tavern_manifest
12
12
  from pybuilder_integration.properties import *
13
13
 
14
14
 
@@ -200,13 +200,21 @@ def _unzip_downloaded_artifacts(dir_with_zips: str, destination: str, logger: Lo
200
200
  os.makedirs(consolidated_folder, exist_ok=True)
201
201
  logger.debug(f"Creating role file for log retrieval {consolidated_folder}/roles")
202
202
  open(f"{consolidated_folder}/roles", 'w').close()
203
+ consolidated_markers = set()
204
+ has_tavern_manifest = False
203
205
  for dirn in os.listdir(f"{destination}/tavern"):
204
206
  if "consolidated" != dirn:
205
207
  logger.debug(f"Consolidating directory: {dirn}")
208
+ markers = read_tavern_service_markers(f"{destination}/tavern/{dirn}")
209
+ if markers is not None:
210
+ has_tavern_manifest = True
211
+ consolidated_markers.update(markers)
206
212
  shutil.copytree(f"{destination}/tavern/{dirn}", consolidated_folder, dirs_exist_ok=True)
207
213
  shutil.rmtree(f"{destination}/tavern/{dirn}")
208
214
  with open(f"{consolidated_folder}/roles", "a") as fp:
209
215
  fp.write(f"{dirn}\n")
216
+ if has_tavern_manifest:
217
+ write_tavern_manifest(consolidated_folder, consolidated_markers)
210
218
  return destination
211
219
 
212
220
 
@@ -0,0 +1,168 @@
1
+ import json
2
+ import os
3
+ import re
4
+ import shutil
5
+ import tempfile
6
+
7
+
8
+ TAVERN_MANIFEST_DIRECTORY = ".pybuilder-integration"
9
+ TAVERN_MANIFEST_FILENAME = "tavern-manifest.json"
10
+ _TAVERN_MARKER_EXCLUSIONS = {"parametrize", "skip", "skipif", "usefixtures", "xfail"}
11
+
12
+
13
+ def prepare_reports_directory(project):
14
+ return prepare_directory("$dir_reports", project)
15
+
16
+
17
+ def prepare_logs_directory(project):
18
+ return prepare_directory("$dir_logs", project)
19
+
20
+
21
+ def prepare_dist_directory(project):
22
+ return prepare_directory("$dir_dist", project)
23
+
24
+
25
+ def prepare_directory(dir_variable, project):
26
+ package__format = f"{dir_variable}/integration"
27
+ reports_dir = project.expand_path(package__format)
28
+ return _ensure_directory_exists(reports_dir)
29
+
30
+
31
+ def _ensure_directory_exists(path):
32
+ if not os.path.exists(path):
33
+ os.makedirs(path)
34
+ return path
35
+
36
+
37
+ def get_working_distribution_directory(project):
38
+ dist_directory = prepare_dist_directory(project)
39
+ return _ensure_directory_exists(f"{dist_directory}/working")
40
+
41
+
42
+ def get_latest_distribution_directory(project):
43
+ dist_directory = prepare_dist_directory(project)
44
+ from pybuilder_integration import ENVIRONMENT
45
+ environment = project.get_mandatory_property(ENVIRONMENT)
46
+ return _ensure_directory_exists(f"{dist_directory}/LATEST-{environment}")
47
+
48
+
49
+ def get_latest_zipped_distribution_directory(project):
50
+ dist_directory = prepare_dist_directory(project)
51
+ from pybuilder_integration import ENVIRONMENT
52
+ environment = project.get_mandatory_property(ENVIRONMENT)
53
+ return _ensure_directory_exists(f"{dist_directory}/LATEST-{environment}/zipped")
54
+
55
+
56
+ def get_local_zip_artifact_path(tool, project, include_ending=False):
57
+ artifact = f"{prepare_dist_directory(project)}/{tool}-{project.name}"
58
+ if include_ending:
59
+ return f"{artifact}.zip"
60
+ return artifact
61
+
62
+
63
+ def get_tavern_manifest_path(test_dir):
64
+ return os.path.join(test_dir, TAVERN_MANIFEST_DIRECTORY, TAVERN_MANIFEST_FILENAME)
65
+
66
+
67
+ def collect_tavern_service_markers(test_dir):
68
+ markers = set()
69
+ for root, _, files in os.walk(test_dir):
70
+ for filename in files:
71
+ if filename.endswith(".tavern.yaml"):
72
+ markers.update(_collect_markers_from_tavern_file(os.path.join(root, filename)))
73
+ return sorted(markers)
74
+
75
+
76
+ def write_tavern_manifest(test_dir, service_markers=None):
77
+ manifest_path = get_tavern_manifest_path(test_dir)
78
+ manifest_directory = os.path.dirname(manifest_path)
79
+ os.makedirs(manifest_directory, exist_ok=True)
80
+ if service_markers is None:
81
+ service_markers = collect_tavern_service_markers(test_dir)
82
+ manifest_content = json.dumps({"service_markers": sorted(service_markers)}).encode("utf-8")
83
+ descriptor, temporary_path = tempfile.mkstemp(prefix=".tavern-manifest-", dir=manifest_directory)
84
+ try:
85
+ bytes_written = 0
86
+ while bytes_written < len(manifest_content):
87
+ written = os.write(descriptor, manifest_content[bytes_written:])
88
+ if written == 0:
89
+ raise OSError("Could not write Tavern marker manifest")
90
+ bytes_written += written
91
+ os.close(descriptor)
92
+ descriptor = None
93
+ os.replace(temporary_path, manifest_path)
94
+ finally:
95
+ if descriptor is not None:
96
+ os.close(descriptor)
97
+ if os.path.exists(temporary_path):
98
+ os.unlink(temporary_path)
99
+
100
+
101
+ def read_tavern_service_markers(test_dir):
102
+ manifest_path = get_tavern_manifest_path(test_dir)
103
+ if not os.path.exists(manifest_path):
104
+ return None
105
+ try:
106
+ with open(manifest_path) as manifest_file:
107
+ manifest = json.load(manifest_file)
108
+ except (OSError, ValueError):
109
+ return None
110
+ markers = manifest.get("service_markers", [])
111
+ if not isinstance(markers, list) or not all(isinstance(marker, str) for marker in markers):
112
+ return None
113
+ return set(markers)
114
+
115
+
116
+ def _collect_markers_from_tavern_file(path):
117
+ markers = set()
118
+ in_marks = False
119
+ marks_indent = 0
120
+ with open(path) as tavern_file:
121
+ for line in tavern_file:
122
+ match = re.match(r"^(\s*)marks:\s*(.*)$", line)
123
+ if match:
124
+ in_marks = True
125
+ marks_indent = len(match.group(1))
126
+ inline_markers = match.group(2).strip()
127
+ if inline_markers.startswith("[") and inline_markers.endswith("]"):
128
+ for marker in inline_markers[1:-1].split(","):
129
+ _add_tavern_marker(markers, marker)
130
+ continue
131
+ if not in_marks:
132
+ continue
133
+ if not line.strip() or line.lstrip().startswith("#"):
134
+ continue
135
+ indent = len(line) - len(line.lstrip())
136
+ if indent <= marks_indent:
137
+ in_marks = False
138
+ continue
139
+ marker = re.match(r"^\s*-\s*(.+?)\s*(?:#.*)?$", line)
140
+ if marker:
141
+ _add_tavern_marker(markers, marker.group(1))
142
+ return markers
143
+
144
+
145
+ def _add_tavern_marker(markers, value):
146
+ marker = value.strip().strip("'\"")
147
+ if re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", marker) and marker not in _TAVERN_MARKER_EXCLUSIONS:
148
+ markers.add(marker)
149
+
150
+
151
+ def package_artifacts(project, test_dir, tool, role):
152
+ # Make a copy for easy access in environment validation
153
+ working_dir = get_working_distribution_directory(project)
154
+ shutil.copytree(test_dir, f"{working_dir}/{tool}",dirs_exist_ok=True)
155
+ if tool == "tavern":
156
+ write_tavern_manifest(f"{working_dir}/{tool}")
157
+ with tempfile.TemporaryDirectory() as tempdir:
158
+ shutil.copytree(test_dir, f"{tempdir}/{role}",dirs_exist_ok=True)
159
+ if tool == "tavern":
160
+ write_tavern_manifest(f"{tempdir}/{role}")
161
+ # package a copy for distribution
162
+ # zip up the test and add them to the integration test dist directory
163
+ base_name = get_local_zip_artifact_path(tool=tool, project=project)
164
+ shutil.make_archive(base_name=base_name,
165
+ base_dir=role,
166
+ format="zip",
167
+ root_dir=tempdir)
168
+
@@ -17,6 +17,7 @@ APPLICATION = "application"
17
17
  APPLICATION_GROUP = "application_group"
18
18
  RUN_PARALLEL = "pytest_parallel"
19
19
  CONSOLIDATE_TESTS = "consolidate_tavern"
20
+ SKIP_NON_MATCHING_TAVERN_ARTIFACTS = "skip_non_matching_tavern_artifacts"
20
21
  TESTING_SCOPE = "testing_scope"
21
22
  PARALLEL_VERIFY_ENVIRONMENT = "parallel_verify_environment"
22
23
  SUBPROCESS_PROPERTIES_FILE_ENV = "PYBUILDER_INTEGRATION_PROPERTIES_FILE"
@@ -3,9 +3,10 @@ import os
3
3
  import re
4
4
  import shutil
5
5
  import subprocess
6
- import sys
7
6
  import tempfile
8
- import xml.etree.ElementTree as ET
7
+
8
+ from defusedxml import ElementTree as ET
9
+ from defusedxml.common import DefusedXmlException
9
10
 
10
11
  import pytest
11
12
  from pybuilder.core import Project, Logger, RequirementsFile
@@ -18,7 +19,8 @@ from pybuilder_integration import exec_utility, tool_utility, directory_utility
18
19
  from pybuilder_integration.artifact_manager import get_artifact_manager
19
20
  from pybuilder_integration.cloudwatchlogs_utility import CloudwatchLogs
20
21
  from pybuilder_integration.directory_utility import get_working_distribution_directory, \
21
- package_artifacts, prepare_reports_directory, get_local_zip_artifact_path, prepare_logs_directory
22
+ package_artifacts, prepare_reports_directory, get_local_zip_artifact_path, prepare_logs_directory, \
23
+ read_tavern_service_markers
22
24
  from pybuilder_integration.properties import *
23
25
  from pybuilder_integration.tool_utility import install_cypress
24
26
 
@@ -26,6 +28,7 @@ from pybuilder_integration.tool_utility import install_cypress
26
28
  _VERIFY_ENVIRONMENT_SUBPROCESS_PROPERTIES = [
27
29
  INTEGRATION_ARTIFACT_BUCKET,
28
30
  ENVIRONMENT,
31
+ ENVIRONMENT_VARIABLES,
29
32
  ARTIFACT_MANAGER,
30
33
  CYPRESS_TEST_DIR,
31
34
  CYPRESS_CONFIG_FILE,
@@ -40,6 +43,7 @@ _VERIFY_ENVIRONMENT_SUBPROCESS_PROPERTIES = [
40
43
  APPLICATION_GROUP,
41
44
  RUN_PARALLEL,
42
45
  CONSOLIDATE_TESTS,
46
+ SKIP_NON_MATCHING_TAVERN_ARTIFACTS,
43
47
  TESTING_SCOPE,
44
48
  "abort_upload",
45
49
  "record_cypress",
@@ -132,10 +136,54 @@ def _run_verify_environment_passes_in_subprocesses(project: Project, logger: Log
132
136
  if failures:
133
137
  raise BuildFailedException("Parallel verify_environment failed: " + "; ".join(failures))
134
138
  finally:
139
+ for _, process, _ in processes:
140
+ poll = getattr(process, "poll", None)
141
+ if callable(poll) and poll() is None:
142
+ process.terminate()
143
+ process.wait()
144
+ log_handle = getattr(process, "_pybuilder_integration_log_handle", None)
145
+ if log_handle and not log_handle.closed:
146
+ log_handle.close()
147
+ _merge_parallel_verify_environment_outputs(project, passes)
135
148
  if os.path.exists(properties_file):
136
149
  os.remove(properties_file)
137
150
 
138
151
 
152
+ def _merge_parallel_verify_environment_outputs(project: Project, passes):
153
+ parent_target = project.expand_path("$dir_target")
154
+ parent_logs_directory = prepare_logs_directory(project)
155
+ parent_output_directories = [
156
+ ("logs", parent_logs_directory),
157
+ ("reports", prepare_reports_directory(project)),
158
+ ]
159
+ parent_cypress_log = os.path.join(parent_logs_directory, "cypress_run.log")
160
+ has_parent_cypress_log = False
161
+ for pass_config in passes:
162
+ stage_target = os.path.join(parent_target, "verify_environment", pass_config["name"])
163
+ for output_directory, destination_directory in parent_output_directories:
164
+ source = os.path.join(stage_target, output_directory, "integration")
165
+ if os.path.exists(source):
166
+ destination = os.path.join(
167
+ destination_directory,
168
+ "parallel",
169
+ pass_config["name"],
170
+ )
171
+ shutil.copytree(source, destination, dirs_exist_ok=True)
172
+ if output_directory == "logs":
173
+ cypress_log = os.path.join(source, "cypress_run.log")
174
+ if os.path.exists(cypress_log):
175
+ _copy_cypress_log(cypress_log, parent_cypress_log, has_parent_cypress_log)
176
+ has_parent_cypress_log = True
177
+
178
+
179
+ def _copy_cypress_log(source, destination, append):
180
+ flags = os.O_WRONLY | os.O_CREAT | (os.O_APPEND if append else os.O_TRUNC)
181
+ mode = "ab" if append else "wb"
182
+ with open(source, "rb") as source_file:
183
+ with os.fdopen(os.open(destination, flags, 0o600), mode) as destination_file:
184
+ shutil.copyfileobj(source_file, destination_file)
185
+
186
+
139
187
  def _start_verify_environment_subprocess(project: Project, logger: Logger, pass_config, properties_file):
140
188
  log_file = os.path.join(prepare_logs_directory(project), f"verify_environment_{pass_config['name']}.log")
141
189
  command = _build_verify_environment_subprocess_command(project, pass_config)
@@ -164,9 +212,7 @@ def _start_verify_environment_subprocess(project: Project, logger: Logger, pass_
164
212
  def _build_verify_environment_subprocess_command(project: Project, pass_config):
165
213
  stage_target = os.path.join(project.expand_path("$dir_target"), "verify_environment", pass_config["name"])
166
214
  return [
167
- sys.executable,
168
- "-c",
169
- "from pybuilder.cli import main; main()",
215
+ "pyb",
170
216
  pass_config["task"],
171
217
  "-P", f"{WORKING_TEST_DIR}={pass_config['test_dir']}",
172
218
  "-P", f"{PARALLEL_VERIFY_ENVIRONMENT}=False",
@@ -189,13 +235,12 @@ def _collect_json_safe_project_properties(project: Project):
189
235
  safe_properties = {}
190
236
  for name in _VERIFY_ENVIRONMENT_SUBPROCESS_PROPERTIES:
191
237
  value = project.get_property(name, None)
192
- if value is None:
193
- continue
194
- try:
195
- json.dumps(value)
196
- except (TypeError, ValueError):
197
- continue
198
- safe_properties[name] = value
238
+ if value is not None:
239
+ try:
240
+ json.dumps(value)
241
+ except (TypeError, ValueError):
242
+ continue
243
+ safe_properties[name] = value
199
244
  return safe_properties
200
245
 
201
246
 
@@ -374,7 +419,7 @@ def _build_cypress_summary(log_path):
374
419
  name = tc.get("name", "")
375
420
  msg = (failure.get("message") or failure.text or "").split("\n")[0][:120]
376
421
  failures.append((f"{suite} > {name}", msg))
377
- except ET.ParseError:
422
+ except (ET.ParseError, DefusedXmlException):
378
423
  pass
379
424
 
380
425
  passed = total - failed - skipped
@@ -449,6 +494,15 @@ def _run_tavern_tests_in_dir(test_dir: str, logger: Logger, project: Project, re
449
494
  logger.info(f"Found {len(os.listdir(test_dir))} files in tavern test directory")
450
495
  # todo is this unique enough for each run?
451
496
  output_file, run_name = get_test_report_file(project, test_dir)
497
+ extra_args = [project.expand(prop) for prop in project.get_property(TAVERN_ADDITIONAL_ARGS, [])]
498
+ requested_marker = _extract_tavern_marker_filter(extra_args)
499
+ declared_markers = read_tavern_service_markers(test_dir)
500
+ skip_non_matching_artifacts = _get_bool_property(project, SKIP_NON_MATCHING_TAVERN_ARTIFACTS, False)
501
+ if skip_non_matching_artifacts and requested_marker and declared_markers and requested_marker not in declared_markers:
502
+ logger.info(
503
+ f"Skipping Tavern tests: artifact markers {sorted(declared_markers)} do not match {requested_marker}"
504
+ )
505
+ return True
452
506
  from sys import path as syspath
453
507
  syspath.insert(0, test_dir)
454
508
  # install any requirements that my exist
@@ -457,7 +511,6 @@ def _run_tavern_tests_in_dir(test_dir: str, logger: Logger, project: Project, re
457
511
  dependency = RequirementsFile(requirements_file)
458
512
  install_dependencies(logger, project, dependency, reactor.pybuilder_venv,
459
513
  f"{prepare_logs_directory(project)}/install_tavern_pip_dependencies.log")
460
- extra_args = [project.expand(prop) for prop in project.get_property(TAVERN_ADDITIONAL_ARGS, [])]
461
514
  args = ["--junit-xml", f"{output_file}", test_dir] + extra_args
462
515
  if project.get_property("verbose"):
463
516
  args.append("-s")
@@ -476,7 +529,7 @@ def _run_tavern_tests_in_dir(test_dir: str, logger: Logger, project: Project, re
476
529
  ret = pytest.main(args)
477
530
  if ret == pytest.ExitCode.NO_TESTS_COLLECTED:
478
531
  fallback_args = _without_tavern_marker_filter(args)
479
- if fallback_args != args:
532
+ if fallback_args != args and (not skip_non_matching_artifacts or not declared_markers):
480
533
  logger.warn(
481
534
  "No Tavern tests matched the marker filter; rerunning the full suite"
482
535
  )
@@ -519,6 +572,19 @@ def _without_tavern_marker_filter(args):
519
572
  return fallback_args
520
573
 
521
574
 
575
+ def _extract_tavern_marker_filter(args):
576
+ for index, arg in enumerate(args):
577
+ if arg in {"-m", "--markexpr"} and index + 1 < len(args):
578
+ marker = args[index + 1]
579
+ elif arg.startswith("--markexpr="):
580
+ marker = arg.split("=", 1)[1]
581
+ else:
582
+ continue
583
+ if marker.replace("_", "").isalnum() and marker:
584
+ return marker
585
+ return None
586
+
587
+
522
588
  def get_test_report_file(project, test_dir, tool="tavern"):
523
589
  run_name = os.path.basename(test_dir)
524
590
  output_file = os.path.join(prepare_reports_directory(project), f"{tool}-{run_name}.out.xml")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybuilder-integration
3
- Version: 104
3
+ Version: 106
4
4
  Summary: A pybuilder plugin that runs integration tests (Tavern & Cypress) against a target.
5
5
  Home-page: https://github.com/rspitler/pybuilder-integration
6
6
  Author:
@@ -10,9 +10,10 @@ Maintainer-email:
10
10
  License: Apache 2.0
11
11
  Classifier: Development Status :: 3 - Alpha
12
12
  Classifier: Programming Language :: Python
13
- Requires-Dist: pytest
13
+ Requires-Dist: pytest==7.4.4
14
14
  Requires-Dist: tavern==1.25.2
15
- Requires-Dist: boto3
15
+ Requires-Dist: boto3==1.43.72
16
+ Requires-Dist: defusedxml==0.7.1
16
17
  Dynamic: classifier
17
18
  Dynamic: description
18
19
  Dynamic: home-page
@@ -0,0 +1,4 @@
1
+ pytest==7.4.4
2
+ tavern==1.25.2
3
+ boto3==1.43.72
4
+ defusedxml==0.7.1
@@ -21,7 +21,7 @@ class install(_install):
21
21
  if __name__ == '__main__':
22
22
  setup(
23
23
  name = 'pybuilder-integration',
24
- version = '104',
24
+ version = '106',
25
25
  description = 'A pybuilder plugin that runs integration tests (Tavern & Cypress) against a target.',
26
26
  long_description = 'A pybuilder plugin that runs integration tests against a target. This is intended to be a broader scope than unit-tests encompassing dependant functionality.',
27
27
  long_description_content_type = None,
@@ -49,9 +49,10 @@ if __name__ == '__main__':
49
49
  data_files = [],
50
50
  package_data = {},
51
51
  install_requires = [
52
- 'pytest',
52
+ 'pytest==7.4.4',
53
53
  'tavern==1.25.2',
54
- 'boto3'
54
+ 'boto3==1.43.72',
55
+ 'defusedxml==0.7.1'
55
56
  ],
56
57
  extras_require = {},
57
58
  dependency_links = [],
@@ -1,70 +0,0 @@
1
- import os
2
- import shutil
3
- import tempfile
4
-
5
-
6
-
7
- def prepare_reports_directory(project):
8
- return prepare_directory("$dir_reports", project)
9
-
10
-
11
- def prepare_logs_directory(project):
12
- return prepare_directory("$dir_logs", project)
13
-
14
-
15
- def prepare_dist_directory(project):
16
- return prepare_directory("$dir_dist", project)
17
-
18
-
19
- def prepare_directory(dir_variable, project):
20
- package__format = f"{dir_variable}/integration"
21
- reports_dir = project.expand_path(package__format)
22
- return _ensure_directory_exists(reports_dir)
23
-
24
-
25
- def _ensure_directory_exists(path):
26
- if not os.path.exists(path):
27
- os.makedirs(path)
28
- return path
29
-
30
-
31
- def get_working_distribution_directory(project):
32
- dist_directory = prepare_dist_directory(project)
33
- return _ensure_directory_exists(f"{dist_directory}/working")
34
-
35
-
36
- def get_latest_distribution_directory(project):
37
- dist_directory = prepare_dist_directory(project)
38
- from pybuilder_integration import ENVIRONMENT
39
- environment = project.get_mandatory_property(ENVIRONMENT)
40
- return _ensure_directory_exists(f"{dist_directory}/LATEST-{environment}")
41
-
42
-
43
- def get_latest_zipped_distribution_directory(project):
44
- dist_directory = prepare_dist_directory(project)
45
- from pybuilder_integration import ENVIRONMENT
46
- environment = project.get_mandatory_property(ENVIRONMENT)
47
- return _ensure_directory_exists(f"{dist_directory}/LATEST-{environment}/zipped")
48
-
49
-
50
- def get_local_zip_artifact_path(tool, project, include_ending=False):
51
- artifact = f"{prepare_dist_directory(project)}/{tool}-{project.name}"
52
- if include_ending:
53
- return f"{artifact}.zip"
54
- return artifact
55
-
56
-
57
- def package_artifacts(project, test_dir, tool, role):
58
- # Make a copy for easy access in environment validation
59
- working_dir = get_working_distribution_directory(project)
60
- shutil.copytree(test_dir, f"{working_dir}/{tool}",dirs_exist_ok=True)
61
- with tempfile.TemporaryDirectory() as tempdir:
62
- shutil.copytree(test_dir, f"{tempdir}/{role}",dirs_exist_ok=True)
63
- # package a copy for distribution
64
- # zip up the test and add them to the integration test dist directory
65
- base_name = get_local_zip_artifact_path(tool=tool, project=project)
66
- shutil.make_archive(base_name=base_name,
67
- base_dir=role,
68
- format="zip",
69
- root_dir=tempdir)
70
-
@@ -1,3 +0,0 @@
1
- pytest
2
- tavern==1.25.2
3
- boto3