forked from pulp/pulp_docker
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Read/use Directory Transport version from Skopeo
Adds comparators for a new class Version which represents a skopeo directory transport version. This will allow us to easily support future changes. containers/image#419 fixes: #3703
- Loading branch information
Showing
4 changed files
with
280 additions
and
10 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
class Version: | ||
""" | ||
Represents a version of a Skopeo Directory Transport version file. | ||
This class enables rich comparisons between versions. All comparisons are implemented because | ||
functools.total_ordering is not available in Python 2.6. | ||
""" | ||
def __init__(self, version): | ||
""" | ||
Args: | ||
version (str): version number | ||
""" | ||
self.version = version | ||
|
||
@classmethod | ||
def from_file(cls, path): | ||
""" | ||
Creates a Version from a Skopeo version file. | ||
Args: | ||
path (str): path to the version file | ||
Return: | ||
(Version): instance | ||
Raises: | ||
(IOError): when path does not exist | ||
""" | ||
with open(path) as version_file: | ||
version = version_file.readline().split(':')[1].strip() | ||
return cls(version) | ||
|
||
@property | ||
def components(self): | ||
""" | ||
Return: | ||
(tuple) of 2 integer components of the release, (X, Y) | ||
""" | ||
components = [int(comp) for comp in self.version.split(".")] | ||
assert len(components) == 2, "Directory Transport Versions must be in the form X.Y" | ||
return tuple(components) | ||
|
||
def __eq__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self == other | ||
""" | ||
return self.version == other.version | ||
|
||
def __ne__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self != other | ||
""" | ||
return not self.version == other.version | ||
|
||
def __gt__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self > other | ||
""" | ||
comparisons = zip(self.components, other.components) | ||
for s, o in comparisons: | ||
if s != o: | ||
return s > o | ||
return False | ||
|
||
def __ge__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self >= other | ||
""" | ||
op_result = self.__gt__(other) | ||
return op_result or self == other | ||
|
||
def __lt__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self < other | ||
""" | ||
comparisons = zip(self.components, other.components) | ||
for s, o in comparisons: | ||
if s != o: | ||
return not s > o | ||
|
||
def __le__(self, other): | ||
""" | ||
Args: | ||
other (Version): version to compare with | ||
Return: | ||
(bool) True if self <= other | ||
""" | ||
op_result = self.__lt__(other) | ||
return op_result or self == other | ||
|
||
def __repr__(self): | ||
""" | ||
Return: | ||
(string) in the format that skopeo uses. | ||
""" | ||
return "Directory Transport Version: {v}\n".format(v=self.version) |
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,80 @@ | ||
import mock | ||
import unittest | ||
|
||
from pulp_docker.common import transport | ||
|
||
|
||
class TestVersion(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.v00 = transport.Version("0.0") | ||
self.v10 = transport.Version("1.0") | ||
self.v11 = transport.Version("1.1") | ||
self.v199 = transport.Version("1.99") | ||
self.v20 = transport.Version("2.0") | ||
self.copy_v11 = transport.Version("1.1") | ||
self.copy_v00 = transport.Version("0.0") | ||
|
||
def test_read(self): | ||
""" | ||
Ensure that the file line is correctly parsed. | ||
""" | ||
mock_version = "Directory Transport Version: 1.1\n" | ||
with mock.patch('pulp_docker.common.transport.open', create=True) as mopen: | ||
mock_readline = mopen.return_value.__enter__.return_value.readline | ||
mock_readline.return_value = mock_version | ||
version = transport.Version.from_file("path-to-version") | ||
|
||
self.assertEqual(version.version, '1.1') | ||
|
||
def test_read_nonexistant(self): | ||
try: | ||
with mock.patch('pulp_docker.common.transport.open', create=True) as mopen: | ||
mopen.side_effect = IOError | ||
transport.Version.from_file("path-to-version") | ||
except IOError: | ||
pass | ||
else: | ||
raise AssertionError("IOError from open should bubble up.") | ||
|
||
def test_eq(self): | ||
self.assertTrue(self.v11 == self.copy_v11) | ||
self.assertTrue(self.v00 == self.copy_v00) | ||
|
||
self.assertFalse(self.v10 == self.v11) | ||
|
||
def test_inequality(self): | ||
self.assertTrue(self.v10 != self.v11) | ||
|
||
self.assertFalse(self.v00 != self.copy_v00) | ||
self.assertFalse(self.v11 != self.copy_v11) | ||
|
||
def test_gt(self): | ||
self.assertTrue(self.v11 > self.v10) | ||
|
||
self.assertFalse(self.v10 > self.v11) | ||
self.assertFalse(self.v11 > self.copy_v11) | ||
|
||
def test_gt_for_large_y_release(self): | ||
self.assertTrue(self.v20 > self.v199) | ||
|
||
def test_ge(self): | ||
self.assertTrue(self.v10 >= self.v10) | ||
self.assertTrue(self.v11 >= self.v10) | ||
|
||
self.assertFalse(self.v10 >= self.v11) | ||
|
||
def test_lt(self): | ||
self.assertTrue(self.v10 < self.v11) | ||
|
||
self.assertFalse(self.v11 < self.v00) | ||
self.assertFalse(self.v11 < self.copy_v11) | ||
|
||
def test_lt_for_large_y_release(self): | ||
self.assertTrue(self.v199 < self.v20) | ||
|
||
def test_le(self): | ||
self.assertTrue(self.v10 <= self.v10) | ||
self.assertTrue(self.v10 <= self.v11) | ||
|
||
self.assertFalse(self.v11 <= self.v10) |
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