devopsdriver 0.1.44__tar.gz → 0.1.45__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.
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/PKG-INFO +5 -5
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/README.md +1 -1
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/__init__.py +1 -1
- devopsdriver-0.1.45/devopsdriver/azdo/builds/__init__.py +0 -0
- devopsdriver-0.1.45/devopsdriver/azdo/builds/build.py +74 -0
- devopsdriver-0.1.45/devopsdriver/azdo/builds/client.py +59 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/clients.py +2 -1
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/dataobject.py +9 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/PKG-INFO +5 -5
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/SOURCES.txt +5 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/requires.txt +2 -2
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/pyproject.toml +3 -3
- devopsdriver-0.1.45/tests/test_azure_build.py +99 -0
- devopsdriver-0.1.45/tests/test_azure_build_client.py +76 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/LICENSE +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/__init__.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/azureobject.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/pipeline/__init__.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/pipeline/client.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/pipeline/log.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/pipeline/pipeline.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/pipeline/run.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/timestamp.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/workitem/__init__.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/workitem/client.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/azdo/workitem/wiql.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/manage_settings.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/sendmail.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/settings.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/template.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver/templates/manage_settings.txt.mako +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/dependency_links.txt +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/entry_points.txt +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/devopsdriver.egg-info/top_level.txt +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/setup.cfg +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_azureobject.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_clients.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_pipeline.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_pipeline_client.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_pipeline_run.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_timestamp.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_workitem_client.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_azure_workitem_wiql.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_dataobject.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_manage_settings.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_sendmail.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_settings.py +0 -0
- {devopsdriver-0.1.44 → devopsdriver-0.1.45}/tests/test_template.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devopsdriver
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.45
|
|
4
4
|
Summary: DevOps tools
|
|
5
5
|
Author-email: Marc Page <marcallenpage@gmail.com>
|
|
6
6
|
License: This is free and unencumbered software released into the public domain.
|
|
@@ -40,7 +40,7 @@ Classifier: Intended Audience :: Developers
|
|
|
40
40
|
Classifier: Programming Language :: Python
|
|
41
41
|
Classifier: Programming Language :: Python :: 3
|
|
42
42
|
Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
|
|
43
|
-
Classifier: Programming Language :: Python :: 3.
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
44
44
|
Classifier: Topic :: Utilities
|
|
45
45
|
Classifier: Topic :: Software Development
|
|
46
46
|
Requires-Python: >=3.10
|
|
@@ -48,9 +48,9 @@ Description-Content-Type: text/markdown
|
|
|
48
48
|
License-File: LICENSE
|
|
49
49
|
Requires-Dist: PyYAML==6.0.1
|
|
50
50
|
Requires-Dist: keyring==25.1.0
|
|
51
|
-
Requires-Dist: setuptools==69.
|
|
51
|
+
Requires-Dist: setuptools==69.5.1
|
|
52
52
|
Requires-Dist: azure-devops==7.1.0b4
|
|
53
|
-
Requires-Dist: Mako==1.3.
|
|
53
|
+
Requires-Dist: Mako==1.3.3
|
|
54
54
|
Provides-Extra: dev
|
|
55
55
|
Requires-Dist: black>=24.3.0; extra == "dev"
|
|
56
56
|
Requires-Dist: pylint>=3.1.0; extra == "dev"
|
|
@@ -60,7 +60,7 @@ Requires-Dist: coverage>=7.4.4; extra == "test"
|
|
|
60
60
|
Provides-Extra: doc
|
|
61
61
|
|
|
62
62
|

|
|
63
|
-
[](https://pypi.org/project/devopsdriver/0.1.45/)
|
|
64
64
|
[](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
|
|
65
65
|
[](https://github.com/marcpage/devops-driver/graphs/contributors)
|
|
66
66
|
[](http://makeapullrequest.com)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|

|
|
2
|
-
[](https://pypi.org/project/devopsdriver/0.1.45/)
|
|
3
3
|
[](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
|
|
4
4
|
[](https://github.com/marcpage/devops-driver/graphs/contributors)
|
|
5
5
|
[](http://makeapullrequest.com)
|
|
File without changes
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
""" Azure Build """
|
|
4
|
+
|
|
5
|
+
from azure.devops.v7_1.build.models import Build as AzureBuild
|
|
6
|
+
from azure.devops.v7_1.build import BuildClient
|
|
7
|
+
from azure.devops.v7_1.build.models import TimelineRecord
|
|
8
|
+
|
|
9
|
+
from devopsdriver.azdo import AzureObject
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Build(AzureObject): # pylint: disable=too-few-public-methods
|
|
13
|
+
"""Azure Build"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: BuildClient, build: AzureBuild):
|
|
16
|
+
self.client = client
|
|
17
|
+
self.build = build
|
|
18
|
+
super().__init__(build)
|
|
19
|
+
|
|
20
|
+
class Step(AzureObject): # pylint: disable=too-few-public-methods
|
|
21
|
+
"""Azure Build Step (job, task, step)"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, entry: TimelineRecord):
|
|
24
|
+
self.children = []
|
|
25
|
+
self.log_contents: str = None
|
|
26
|
+
super().__init__(entry)
|
|
27
|
+
|
|
28
|
+
def all_logs(self) -> list[str]:
|
|
29
|
+
"""Get a list of all logs in chronological order
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
list[str]: List of all the logs
|
|
33
|
+
"""
|
|
34
|
+
logs = [] if self.log_contents is None else [self.log_contents]
|
|
35
|
+
|
|
36
|
+
for child in self.children:
|
|
37
|
+
logs.extend(child.all_logs())
|
|
38
|
+
|
|
39
|
+
return logs
|
|
40
|
+
|
|
41
|
+
def __add_steps_and_logs(self, entry: Step, to_process: list[Step]) -> Step:
|
|
42
|
+
project = self.build.project.name
|
|
43
|
+
build_id = self.build.id
|
|
44
|
+
|
|
45
|
+
if entry.log:
|
|
46
|
+
entry.log_contents = "\n".join(
|
|
47
|
+
self.client.get_build_log_lines(project, build_id, entry.log.id)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
entry.children = [e for e in to_process if e.parent_id == entry.id]
|
|
51
|
+
|
|
52
|
+
for child in entry.children:
|
|
53
|
+
to_process.remove(child)
|
|
54
|
+
self.__add_steps_and_logs(child, to_process)
|
|
55
|
+
|
|
56
|
+
return entry
|
|
57
|
+
|
|
58
|
+
def get_logs(self) -> Step:
|
|
59
|
+
"""Gets the logs in a hierarchical structure
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Step: The root element of the log hierarchy
|
|
63
|
+
"""
|
|
64
|
+
project = self.build.project.name
|
|
65
|
+
build_id = self.build.id
|
|
66
|
+
steps = [
|
|
67
|
+
Build.Step(r)
|
|
68
|
+
for r in self.client.get_build_timeline(project, build_id).records
|
|
69
|
+
]
|
|
70
|
+
root = [s for s in steps if not s.parent_id]
|
|
71
|
+
assert len(root) == 1, root
|
|
72
|
+
root = root[0]
|
|
73
|
+
steps.remove(root)
|
|
74
|
+
return self.__add_steps_and_logs(root, steps)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
""" Azure Build Client """
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from azure.devops.v7_1.build import BuildClient
|
|
9
|
+
|
|
10
|
+
from .build import Build
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Client: # pylint: disable=too-few-public-methods
|
|
14
|
+
"""The Build client"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, client: BuildClient):
|
|
17
|
+
self.client = client
|
|
18
|
+
|
|
19
|
+
def list( # pylint: disable=too-many-arguments
|
|
20
|
+
self,
|
|
21
|
+
project: str,
|
|
22
|
+
pipelines: list[int] = None,
|
|
23
|
+
start: datetime = None,
|
|
24
|
+
end: datetime = None,
|
|
25
|
+
status: str = None,
|
|
26
|
+
result: str = None,
|
|
27
|
+
properties: list[str] = None,
|
|
28
|
+
branch: str = None,
|
|
29
|
+
) -> list[Build]:
|
|
30
|
+
"""Get the list of builds
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
project (str): The name of the project
|
|
34
|
+
pipelines (list[int], optional): List of pipeline ids. Defaults to None.
|
|
35
|
+
start (datetime, optional): Earliest time. Defaults to None.
|
|
36
|
+
end (datetime, optional): Latest time. Defaults to None.
|
|
37
|
+
status (str, optional): The status to get. Defaults to None.
|
|
38
|
+
result (str, optional): The result to get. Defaults to None.
|
|
39
|
+
properties (list[str], optional): List or properties to return. Defaults to None.
|
|
40
|
+
branch (str, optional): The branch to search. Defaults to None.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
list[Build]: List of all the builds that match the given criteria
|
|
44
|
+
"""
|
|
45
|
+
continuation = None
|
|
46
|
+
return [
|
|
47
|
+
Build(self.client, b)
|
|
48
|
+
for b in self.client.get_builds(
|
|
49
|
+
project,
|
|
50
|
+
continuation_token=continuation,
|
|
51
|
+
definitions=pipelines,
|
|
52
|
+
min_time=start,
|
|
53
|
+
max_time=end,
|
|
54
|
+
status_filter=status,
|
|
55
|
+
result_filter=result,
|
|
56
|
+
properties=properties,
|
|
57
|
+
branch_name=branch,
|
|
58
|
+
)
|
|
59
|
+
]
|
|
@@ -14,6 +14,7 @@ from msrest.authentication import BasicAuthentication as MSBasicAuthentication
|
|
|
14
14
|
from devopsdriver.settings import Settings
|
|
15
15
|
from devopsdriver.azdo.workitem.client import Client as WIClient
|
|
16
16
|
from devopsdriver.azdo.pipeline.client import Client as PLClient
|
|
17
|
+
from devopsdriver.azdo.builds.client import Client as BClient
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
# for testing
|
|
@@ -60,7 +61,7 @@ class Azure: # pylint: disable=too-few-public-methods,too-many-instance-attribu
|
|
|
60
61
|
self.core = Azure._Client(Azure.__client("core", clients, client_calls))
|
|
61
62
|
self.task = Azure._Client(Azure.__client("task", clients, client_calls))
|
|
62
63
|
self.git = Azure._Client(Azure.__client("git", clients, client_calls))
|
|
63
|
-
self.build =
|
|
64
|
+
self.build = BClient(Azure.__client("build", clients, client_calls))
|
|
64
65
|
self.identity = Azure._Client(Azure.__client("identity", clients, client_calls))
|
|
65
66
|
|
|
66
67
|
@staticmethod
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
""" Data Objects """
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
from json import dumps
|
|
7
|
+
|
|
8
|
+
|
|
6
9
|
class DataObject: # pylint: disable=too-few-public-methods
|
|
7
10
|
"""dict like object with fuzzy field matching"""
|
|
8
11
|
|
|
@@ -46,6 +49,12 @@ class DataObject: # pylint: disable=too-few-public-methods
|
|
|
46
49
|
def __getattr__(self, name: str) -> any:
|
|
47
50
|
return self._get_field(name, self.data)
|
|
48
51
|
|
|
52
|
+
def __str__(self) -> str:
|
|
53
|
+
return dumps(self.data, indent=2)
|
|
54
|
+
|
|
55
|
+
def __repr__(self) -> str:
|
|
56
|
+
return dumps(self.data, indent=2)
|
|
57
|
+
|
|
49
58
|
class _Dict(dict):
|
|
50
59
|
def __init__(self, dataobject, data: dict):
|
|
51
60
|
self.dataobject = dataobject
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: devopsdriver
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.45
|
|
4
4
|
Summary: DevOps tools
|
|
5
5
|
Author-email: Marc Page <marcallenpage@gmail.com>
|
|
6
6
|
License: This is free and unencumbered software released into the public domain.
|
|
@@ -40,7 +40,7 @@ Classifier: Intended Audience :: Developers
|
|
|
40
40
|
Classifier: Programming Language :: Python
|
|
41
41
|
Classifier: Programming Language :: Python :: 3
|
|
42
42
|
Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
|
|
43
|
-
Classifier: Programming Language :: Python :: 3.
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
44
44
|
Classifier: Topic :: Utilities
|
|
45
45
|
Classifier: Topic :: Software Development
|
|
46
46
|
Requires-Python: >=3.10
|
|
@@ -48,9 +48,9 @@ Description-Content-Type: text/markdown
|
|
|
48
48
|
License-File: LICENSE
|
|
49
49
|
Requires-Dist: PyYAML==6.0.1
|
|
50
50
|
Requires-Dist: keyring==25.1.0
|
|
51
|
-
Requires-Dist: setuptools==69.
|
|
51
|
+
Requires-Dist: setuptools==69.5.1
|
|
52
52
|
Requires-Dist: azure-devops==7.1.0b4
|
|
53
|
-
Requires-Dist: Mako==1.3.
|
|
53
|
+
Requires-Dist: Mako==1.3.3
|
|
54
54
|
Provides-Extra: dev
|
|
55
55
|
Requires-Dist: black>=24.3.0; extra == "dev"
|
|
56
56
|
Requires-Dist: pylint>=3.1.0; extra == "dev"
|
|
@@ -60,7 +60,7 @@ Requires-Dist: coverage>=7.4.4; extra == "test"
|
|
|
60
60
|
Provides-Extra: doc
|
|
61
61
|
|
|
62
62
|

|
|
63
|
-
[](https://pypi.org/project/devopsdriver/0.1.45/)
|
|
64
64
|
[](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
|
|
65
65
|
[](https://github.com/marcpage/devops-driver/graphs/contributors)
|
|
66
66
|
[](http://makeapullrequest.com)
|
|
@@ -17,6 +17,9 @@ devopsdriver/azdo/__init__.py
|
|
|
17
17
|
devopsdriver/azdo/azureobject.py
|
|
18
18
|
devopsdriver/azdo/clients.py
|
|
19
19
|
devopsdriver/azdo/timestamp.py
|
|
20
|
+
devopsdriver/azdo/builds/__init__.py
|
|
21
|
+
devopsdriver/azdo/builds/build.py
|
|
22
|
+
devopsdriver/azdo/builds/client.py
|
|
20
23
|
devopsdriver/azdo/pipeline/__init__.py
|
|
21
24
|
devopsdriver/azdo/pipeline/client.py
|
|
22
25
|
devopsdriver/azdo/pipeline/log.py
|
|
@@ -27,6 +30,8 @@ devopsdriver/azdo/workitem/client.py
|
|
|
27
30
|
devopsdriver/azdo/workitem/wiql.py
|
|
28
31
|
devopsdriver/templates/manage_settings.txt.mako
|
|
29
32
|
tests/test_azure_azureobject.py
|
|
33
|
+
tests/test_azure_build.py
|
|
34
|
+
tests/test_azure_build_client.py
|
|
30
35
|
tests/test_azure_clients.py
|
|
31
36
|
tests/test_azure_pipeline.py
|
|
32
37
|
tests/test_azure_pipeline_client.py
|
|
@@ -8,9 +8,9 @@ requires-python = ">= 3.10"
|
|
|
8
8
|
dependencies = [
|
|
9
9
|
"PyYAML==6.0.1",
|
|
10
10
|
"keyring==25.1.0",
|
|
11
|
-
"setuptools==69.
|
|
11
|
+
"setuptools==69.5.1", # neded for azure-devops to use 7.1 API
|
|
12
12
|
"azure-devops==7.1.0b4",
|
|
13
|
-
"Mako==1.3.
|
|
13
|
+
"Mako==1.3.3",
|
|
14
14
|
]
|
|
15
15
|
keywords = ["azure", "devops", "jira", "confluence", "email", "pipelines", "tools"]
|
|
16
16
|
classifiers=[
|
|
@@ -20,7 +20,7 @@ classifiers=[
|
|
|
20
20
|
"Programming Language :: Python",
|
|
21
21
|
"Programming Language :: Python :: 3",
|
|
22
22
|
"License :: OSI Approved :: The Unlicense (Unlicense)",
|
|
23
|
-
"Programming Language :: Python :: 3.
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
24
|
"Topic :: Utilities",
|
|
25
25
|
"Topic :: Software Development",
|
|
26
26
|
]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
""" Test build object """
|
|
4
|
+
|
|
5
|
+
from types import SimpleNamespace
|
|
6
|
+
|
|
7
|
+
from devopsdriver.azdo.builds.build import Build
|
|
8
|
+
from devopsdriver.azdo.azureobject import AzureObject
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MockTimeline: # pylint: disable=too-few-public-methods
|
|
12
|
+
"""mock timeline"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, d: dict):
|
|
15
|
+
self.d = d
|
|
16
|
+
|
|
17
|
+
def as_dict(self) -> dict:
|
|
18
|
+
"""mock as_dict"""
|
|
19
|
+
return self.d
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MockClient:
|
|
23
|
+
"""mock build client"""
|
|
24
|
+
|
|
25
|
+
def get_build_log_lines(self, project, build_id, log_id) -> list[str]:
|
|
26
|
+
"""mock get_build_log_lines"""
|
|
27
|
+
return [f"project={project}", f"build={build_id}", f"log={log_id}"]
|
|
28
|
+
|
|
29
|
+
def get_build_timeline(self, project, build_id):
|
|
30
|
+
"""mock get_build_timeline"""
|
|
31
|
+
return SimpleNamespace(
|
|
32
|
+
records=[
|
|
33
|
+
MockTimeline(
|
|
34
|
+
{
|
|
35
|
+
"parent_id": None,
|
|
36
|
+
"id": "5",
|
|
37
|
+
"project": project,
|
|
38
|
+
"build_id": build_id,
|
|
39
|
+
"log": {"id": 9},
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
MockTimeline(
|
|
43
|
+
{
|
|
44
|
+
"parent_id": "5",
|
|
45
|
+
"id": "6",
|
|
46
|
+
"project": project,
|
|
47
|
+
"build_id": build_id,
|
|
48
|
+
"log": {"id": 6},
|
|
49
|
+
}
|
|
50
|
+
),
|
|
51
|
+
]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MockBuild(AzureObject): # pylint: disable=too-few-public-methods
|
|
56
|
+
"""mock build client"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, d: dict):
|
|
59
|
+
self.d = d
|
|
60
|
+
super().__init__(self)
|
|
61
|
+
|
|
62
|
+
def as_dict(self) -> dict:
|
|
63
|
+
"""mock as_dict"""
|
|
64
|
+
return self.d
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_basic() -> None:
|
|
68
|
+
"""test basic functionailty"""
|
|
69
|
+
build = Build(MockClient(), MockBuild({"project": {"name": "project"}, "id": 12}))
|
|
70
|
+
logs = build.get_logs().all_logs()
|
|
71
|
+
assert len(logs) == 2, logs
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_azure_object() -> None:
|
|
75
|
+
"""test string conversions for data objects"""
|
|
76
|
+
build = MockBuild({"project": {"name": "project"}, "id": 12})
|
|
77
|
+
assert (
|
|
78
|
+
str(build)
|
|
79
|
+
== """{
|
|
80
|
+
"project": {
|
|
81
|
+
"name": "project"
|
|
82
|
+
},
|
|
83
|
+
"id": 12
|
|
84
|
+
}"""
|
|
85
|
+
), str(build)
|
|
86
|
+
assert (
|
|
87
|
+
repr(build)
|
|
88
|
+
== """{
|
|
89
|
+
"project": {
|
|
90
|
+
"name": "project"
|
|
91
|
+
},
|
|
92
|
+
"id": 12
|
|
93
|
+
}"""
|
|
94
|
+
), repr(build)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
if __name__ == "__main__":
|
|
98
|
+
test_basic()
|
|
99
|
+
test_azure_object()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
""" Test azure build client """
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from devopsdriver.azdo.builds.client import Client
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MockObject:
|
|
11
|
+
"""mock object"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, d: dict):
|
|
14
|
+
self.d = d
|
|
15
|
+
|
|
16
|
+
def as_dict(self) -> dict:
|
|
17
|
+
"""mock as_dict
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
dict: the dict
|
|
21
|
+
"""
|
|
22
|
+
return self.d
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MockClient:
|
|
26
|
+
"""mock build client"""
|
|
27
|
+
|
|
28
|
+
def get_builds(
|
|
29
|
+
self,
|
|
30
|
+
project,
|
|
31
|
+
definitions,
|
|
32
|
+
min_time,
|
|
33
|
+
max_time,
|
|
34
|
+
status_filter,
|
|
35
|
+
result_filter,
|
|
36
|
+
properties,
|
|
37
|
+
branch_name,
|
|
38
|
+
continuation_token=None,
|
|
39
|
+
):
|
|
40
|
+
"""mock get_builds"""
|
|
41
|
+
return [
|
|
42
|
+
MockObject(
|
|
43
|
+
{
|
|
44
|
+
"project": project,
|
|
45
|
+
"pipelines": definitions,
|
|
46
|
+
"start": min_time,
|
|
47
|
+
"end": max_time,
|
|
48
|
+
"status": status_filter,
|
|
49
|
+
"result": result_filter,
|
|
50
|
+
"fields": properties,
|
|
51
|
+
"branch": branch_name,
|
|
52
|
+
"token": continuation_token,
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_basic() -> None:
|
|
59
|
+
"""Test basic functionality"""
|
|
60
|
+
client = Client(MockClient())
|
|
61
|
+
results = client.list(
|
|
62
|
+
"project",
|
|
63
|
+
[1, 2, 3],
|
|
64
|
+
datetime.now(),
|
|
65
|
+
datetime.now(),
|
|
66
|
+
"completed",
|
|
67
|
+
"success",
|
|
68
|
+
["id"],
|
|
69
|
+
"main",
|
|
70
|
+
)
|
|
71
|
+
assert len(results) == 1, results
|
|
72
|
+
assert results[0].project == "project"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
test_basic()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|