Skip to content

Commit

Permalink
fixes for versions update checks + more detailed descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
fmigneault committed Jul 7, 2022
1 parent 357701b commit 0a8c13b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 24 deletions.
20 changes: 13 additions & 7 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ Changes
Changes:
--------
- Add support of `Process` revisions (resolves `#107 <https://github.com/crim-ca/weaver/issues/107>`_).
- Add``PATCH /processes/{processID}`` request, allowing `MINOR` and `PATCH` level modifications that can be applied
to an existing `Process` in order to revise non-execution critical information such as its documented description.
- Add ``PUT /processes/{processID}`` request, allowing `MAJOR` revision to essentially redeploy a new `Process`,
but leaving some form of relationship with the older version by reusing the same `Process` ID.
- Add support of ``{processID}:{version}`` representation in request path and `Job` ``processID`` to reference the
specific `Process` revisions when fetch `Process` description and `Job` status.
- Add search query ``version`` and ``revisions`` to fetch a specific `Process` revision, or all versions history.
- Add ``PATCH /processes/{processID}`` request, allowing ``MINOR`` and ``PATCH`` level modifications that can be
applied to an existing `Process` in order to revise non-execution critical information. Level ``PATCH`` is used to
identify changes with no impact on execution whatsoever, only affecting metadata such as its documented description.
Level ``MINOR`` is used to update components that affect only execution *methodology* (e.g.: sync/async) or `Process`
retrieval, but that do not directly impact *what* is executed (i.e.: the `Application Package` does not change).
- Add ``PUT /processes/{processID}`` request, allowing ``MAJOR`` revision to essentially redeploy a new `Process`,
but leaving some form of relationship with older versions by reusing the same `Process` ID. This ``MAJOR`` update
level implies a relatively critical change to execute the `Process`, such as the addition, removal or modification
of an input or output, directly impacting the `Application Package` definition and parameters the `Process` offers.
- Add support of ``{processID}:{version}`` representation in request path and ``processID`` of the `Job` definition
to reference the specific `Process` revisions when fetching a `Process` description or a `Job` status.
- Add search query ``version`` and ``revisions`` parameters to allow description of a specific `Process` revision, or
listing all its versions history.
- Add more entries in ``links`` referring to `Process` revisions whenever applicable.

Fixes:
Expand Down
7 changes: 4 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,22 @@ def test_is_update_version():
"1.2.4",
"1.3.1",
]
random.shuffle(versions)
random.shuffle(versions) # function must not depend on input order

assert not is_update_version("0.1.0", versions, VersionLevel.PATCH)
assert not is_update_version("1.0.1", versions, VersionLevel.PATCH)
assert not is_update_version("1.2.1", versions, VersionLevel.PATCH)
assert not is_update_version("1.2.3", versions, VersionLevel.PATCH)
assert not is_update_version("1.3.0", versions, VersionLevel.PATCH)
assert not is_update_version("1.3.1", versions, VersionLevel.PATCH)
assert not is_update_version("1.4.5", versions, VersionLevel.PATCH) # no 1.4.x to update from

assert not is_update_version("0.1.0", versions, VersionLevel.MINOR)
assert not is_update_version("0.1.4", versions, VersionLevel.MINOR)
assert not is_update_version("1.2.5", versions, VersionLevel.MINOR)
assert not is_update_version("1.3.2", versions, VersionLevel.MINOR)
assert not is_update_version("2.0.0", versions, VersionLevel.MINOR) # no 2.x to update from
assert not is_update_version("2.1.3", versions, VersionLevel.MINOR)

assert not is_update_version("0.1.0", versions, VersionLevel.MAJOR)
assert not is_update_version("0.1.4", versions, VersionLevel.MAJOR)
Expand All @@ -139,8 +142,6 @@ def test_is_update_version():
assert is_update_version("0.3.0", versions, VersionLevel.MINOR)
assert is_update_version("1.4.0", versions, VersionLevel.MINOR)
assert is_update_version("1.5.0", versions, VersionLevel.MINOR)
assert is_update_version("2.0.0", versions, VersionLevel.MINOR)
assert is_update_version("2.1.3", versions, VersionLevel.MINOR)

assert is_update_version("2.0.0", versions, VersionLevel.MAJOR)
assert is_update_version("2.1.3", versions, VersionLevel.MAJOR)
Expand Down
9 changes: 6 additions & 3 deletions weaver/processes/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,12 +470,15 @@ def _update_deploy_process_version(process, process_overwrite, update_level, con
Handle all necessary update operations of a :term:`Process` definition.
Validate that any specified version for :term:`Process` deployment is valid against any other existing versions.
If the replacement targets another existing process explicitly (update request), perform any necessary database
adjustments to replace the old process references for the creation of the updated process to ensure all versions
and links remain valid against their original references.
Perform any necessary database adjustments to replace the old :term:`Process` references for the creation of the
updated :term:`Process` to ensure all versions and links remain valid against their original references.
:param process: Desired new process definition.
:param process_overwrite: Old process from which update of the definition in database could be required.
:param update_level:
Minimum semantic version level required for this update operation.
If the new :term:`Process` definition did not provide a version explicitly, this level will be used to
automatically infer the following revision number based on the old :term:`Process` reference.
:param container: Any container to retrieve a database connection.
:returns: Process summary with definition retrieved from storage (saved) after all operations were applied.
:raises HTTPException: Relevant error is raised in the even of any erroneous process definition (old and new).
Expand Down
38 changes: 27 additions & 11 deletions weaver/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,17 +646,32 @@ def is_update_version(version, taken_versions, version_level=VersionLevel.PATCH)
"""
Determines if the version corresponds to an available update version of specified level compared to existing ones.
:param version: Version to validate.
If the specified version corresponds to an older version compared to available ones (i.e.: a taken more recent
version also exists), the specified version will have to fit within the version level range to be considered valid.
For example, requesting ``PATCH`` level will require that the specified version is greater than the last available
version against other existing versions with equivalent ``MAJOR.MINOR`` parts. If ``1.2.0`` and ``2.0.0`` were
taken versions, and ``1.2.3`` has to be verified as the update version, it will be considered valid since its
``PATCH`` number ``3`` is greater than all other ``1.2.x`` versions (it falls within the ``[1.2.x, 1.3.x[`` range).
Requesting instead ``MINOR`` level will require that the specified version is greater than the last available
version against existing versions of same ``MAJOR`` part only. Using again the same example values, ``1.3.0``
would be valid since its ``MINOR`` part ``3`` is greater than any other ``1.x`` taken versions. On the other hand,
version ``1.2.4`` would not be valid as ``x = 2`` is already taken by other versions considering same ``1.x``
portion (``PATCH`` part is ignored in this case since ``MINOR`` is requested, and ``2.0.0`` is ignored as not the
same ``MAJOR`` portion of ``1`` as the tested version). Finally, requesting a ``MAJOR`` level will require
necessarily that the specified version is greater than all other existing versions for update, since ``MAJOR`` is
the highest possible semantic part, and higher parts are not available to define an upper version bound.
.. note::
As long as the version level is respected, the actual number of this level and all following ones can be
anything as long as they are not taken. For example, ``PATCH`` with existing ``1.2.3`` does not require that
the update version be ``1.2.4``. It can be ``1.2.5``, ``1.2.24``, etc. as long as ``1.2.x`` is respected.
Similarly, ``MINOR`` update can provide any ``PATCH`` number, since ``1.x`` only must be respected. From
existing ``1.2.3``, ``MINOR`` update could specify ``1.4.99`` as valid version. The ``PATCH`` part does not
need to start back at ``0``.
:param version: Version to validate as potential update revision.
:param taken_versions: Existing versions that cannot be reused.
:param version_level:
Level to consider availability of versions for update.
If the specified version corresponds to an older version compared to available ones, it will have fit within
the specified version level range to be considered valid.
For example, requesting 'PATCH' level will require that the specified version is greater than the last available
version against other existing versions of same 'MAJOR.MINOR' parts. Requesting 'MINOR' level will require that
the specified version is greater than last available version against other existing versions of same 'MAJOR'
part. Finally, requesting 'MAJOR' level will require that the specified version is greater than all other
existing versions for update, since 'MAJOR' is the highest possible semantic part.
:param version_level: Minimum level to consider availability of versions as valid revision number for update.
:return: Status of availability of the version.
"""

Expand Down Expand Up @@ -699,12 +714,13 @@ def _pad_incr(_parts, _index=None): # type: (Tuple[int, ...], Optional[int]) ->
# if found previous version and next version was not already taken
# the requested one must be one above previous one at same semantic level,
# and must be one below the upper semantic level to be an available version
# (eg: if PATCH requested and found min=1.3.4, then max=1.4.0, version can be anything in between)
if version_level == VersionLevel.MAJOR:
min_version = _pad_incr(ver_min[:1], 0)
max_version = (float("inf"), float("inf"), float("inf"))
elif version_level == VersionLevel.MINOR:
min_version = _pad_incr(ver_min[:2], 1)
max_version = _pad_incr(ver_min[:2], 0)
max_version = _pad_incr(ver_min[:1], 0)
elif version_level == VersionLevel.PATCH:
min_version = _pad_incr(ver_min[:3], 2)
max_version = _pad_incr(ver_min[:2], 1)
Expand Down

0 comments on commit 0a8c13b

Please sign in to comment.