Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [VRD-818] Implement
BuildScan
class (#3757)
- Loading branch information
Showing
5 changed files
with
190 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
client/verta/tests/unit_tests/deployment/test_build_scan.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from hypothesis import given, HealthCheck, settings | ||
import pytest | ||
|
||
from tests.unit_tests.strategies import build_scan_dict | ||
|
||
from verta._internal_utils import time_utils | ||
from verta.endpoint.build import BuildScan, ScanProgressEnum, ScanResultEnum | ||
|
||
|
||
@given(build_scan_dict=build_scan_dict()) | ||
def test_instantiation(build_scan_dict): | ||
"""Verify a BuildScan object can be instantated from a dict.""" | ||
build_scan = BuildScan(build_scan_dict) | ||
|
||
assert build_scan.date_updated == time_utils.datetime_from_iso( | ||
build_scan_dict["date_updated"], | ||
) | ||
assert build_scan.progress == ScanProgressEnum(build_scan_dict["scan_status"]) | ||
if build_scan.progress == ScanProgressEnum.SCANNED: | ||
assert build_scan.passed == (build_scan.result == ScanResultEnum.SAFE) | ||
assert build_scan.result == ScanResultEnum(build_scan_dict["safety_status"]) | ||
else: | ||
assert build_scan.passed is False | ||
assert build_scan.result is None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from datetime import datetime | ||
from enum import Enum | ||
from typing import Optional | ||
|
||
from verta._internal_utils import _utils, time_utils | ||
|
||
|
||
class ScanProgressEnum(str, Enum): | ||
"""The current progress of a build scan. | ||
For all intents and purposes, this can be treated as a :class:`str`. | ||
Examples | ||
-------- | ||
.. code-block:: python | ||
assert build.get_scan().progress == "scanned" | ||
""" | ||
|
||
UNSCANNED = "unscanned" | ||
SCANNING = "scanning" | ||
SCANNED = "scanned" | ||
ERROR = "error" | ||
|
||
|
||
class ScanResultEnum(str, Enum): | ||
"""The result of a build scan. | ||
For all intents and purposes, this can be treated as a :class:`str`. | ||
Examples | ||
-------- | ||
.. code-block:: python | ||
assert build.get_scan().result == "safe" | ||
""" | ||
|
||
UNKNOWN = "unknown" | ||
SAFE = "safe" | ||
UNSAFE = "unsafe" | ||
|
||
|
||
class BuildScan: | ||
"""A scan of a Verta model build. | ||
There should not be a need to instantiate this class directly; please use | ||
:meth:`Build.get_scan() <verta.endpoint.build.Build.get_scan>` instead. | ||
Attributes | ||
---------- | ||
date_updated : timezone-aware :class:`~datetime.datetime` | ||
The date and time when this scan was performed/updated. | ||
progress : :class:`ScanProgressEnum` | ||
The current progress of this scan. | ||
result : :class:`ScanResultEnum` or None | ||
The result of this scan. ``None`` is returned if this scan is not yet | ||
finished, and therefore has no result. | ||
passed : bool | ||
Whether this scan finished and passed. This property is for | ||
convenience, equivalent to | ||
.. code-block:: python | ||
(build_scan.progress == "scanned") and (build_scan.result == "safe") | ||
""" | ||
|
||
def __init__(self, json): | ||
self._json = json | ||
|
||
def __repr__(self): | ||
detail_str = f'progress "{self.progress.value}"' | ||
if self.result is not None: | ||
detail_str += f', result "{self.result.value}"' | ||
|
||
return f"<BuildScan ({detail_str})>" | ||
|
||
@classmethod | ||
def _get(cls, conn: _utils.Connection, build_id: int): | ||
url = f"{conn.scheme}://{conn.socket}/api/v1/deployment/builds/{build_id}/scan" | ||
response = _utils.make_request("GET", url, conn) | ||
_utils.raise_for_http_error(response) | ||
|
||
return cls(response.json()) | ||
|
||
@property | ||
def date_updated(self) -> datetime: | ||
return time_utils.datetime_from_iso(self._json["date_updated"]) | ||
|
||
@property | ||
def progress(self) -> ScanProgressEnum: | ||
return ScanProgressEnum(self._json["scan_status"]) | ||
|
||
@property | ||
def result(self) -> Optional[ScanResultEnum]: | ||
if self.progress != ScanProgressEnum.SCANNED: | ||
return None | ||
return ScanResultEnum(self._json["safety_status"]) | ||
|
||
@property | ||
def passed(self) -> bool: | ||
return self.result == ScanResultEnum.SAFE |