17
0

Accepting request 1333659 from devel:languages:python

- Update to 3.9.0
  * Common
    - Support for Python 3.9 which is EOL has been removed.
    - Indicate we also support Python 3.12 (non beta) and Python 3.13.
    - Support for Python 3.8 which is EOL has been removed.
    - Support for Python 3.7 which is EOL has been removed.
    - Types inheriting from ``libcloud.common.types.Type`` have been made hashable.
    - [NTT CIS] Fix invalid comparison in the ``XmlListConfig.__init__()`` method.
    - Update versions of build and packaging tools required to build the package.
  * Compute
    - [OpenStack] Add optional node port ID to attach the floating IP
      in OpenStack ex_attach_floating_ip_to_node function.
    - [OpenStack] Add metadata fields ``os_distro`` and ``os_version``
      provided by OpenStack Image API (if set) to the ``extra`` field
      of the OpenStack NodeImage.
    - [LINODE] Add support for cloud-init metadata support to
      create_node() Add new functions ``create_key_pair``,
      ``list_key_pairs``, and ``get_image``
    - [Azure ARM] Add a new argument to destroy_node() to also delete
      node's managed OS disk as part of the node's deletion.
    - [ECS] Add VPC IP and Elastic IP to ECS node as private and public IP.
    - [Azure ARM] When deleting a node, delete VM OS disk if it's a managed disk.
    - [Azure ARM] Add ``ex_resize_node()`` method.
    - [Equinix Metal] Fix ``list_nodes()`` method so it correctly
      handles NodeSize.ram attribute in case TB is returned.
    - [Equinix Metal] Deprecate facility API and replace it with metros location.
    - [Equinix Metal] Remove all the methods for managing volumes and
      volume snapshots. This functionality hasn't been supported on
      the server side for many years already.
    - [Amazon EC2] Update pricing and sizing data.

OBS-URL: https://build.opensuse.org/request/show/1333659
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-apache-libcloud?expand=0&rev=48
This commit is contained in:
2026-02-18 16:04:26 +00:00
committed by Git OBS Bridge
12 changed files with 198 additions and 522 deletions

Binary file not shown.

View File

@@ -1,19 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQKlBAABCgCPFiEEmXgo3GL3Wc6hidZeLAdUss4GkvMFAmTP0UZfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDk5
NzgyOERDNjJGNzU5Q0VBMTg5RDY1RTJDMDc1NEIyQ0UwNjkyRjMRHHRvbWF6QGFw
YWNoZS5vcmcACgkQLAdUss4GkvOzOg//WBt4g+CvH3qfi2ChvLHSuzjNxszgTnvB
bVkDsvqJNQlZPEQ+a5l/ZLgRYr7L2trOvqqzVBjEmCq8I0u3GYlOwiBRfmEKLKXO
jRlrMME9swRJJ9KS1slaT9vAuZ5RB8wyzAsJfT45QFXLGpgSW3pGQ9KpX0ZBvvCc
FvWZqBR3wCtc7mcq4e6kj/6pR93WszeTmkZC57JFiAQclhxd0/wPecDKOSZT0ro3
vXvN6Bm5m0NOIx8zAQpyPprT3EIHXp3FiBTPzqwZQVtcPsx5upjswMknEBlj2L9G
JhOh3Emq29byWKtM/++dF1QCICieCmDcW/4Bk1kyslXyloC2SeiBhr1u4gdL6tlO
L5Z1zcLjl8McCWVBbTjNbn9H92t3TPozgSVx2+e4Zsb0T5XirQL2iwCfoZAscjrX
DrvbY9bzSvrjz1EDoxqp3/oN8nUeHMVd7eQfx4aOnr1cAWROlRNSHx2p1De8Gamx
7nbyaFsdJSwIeTn6CtJ6vpWzqtwWdBYlJrOkhv33ElPD+KhHUsv92utE809weCfY
PdFruz8Hu2FvIOiqJQD7sMSfo+FWz22kKzz/Sv0TqL4qIjfoMyFYQ/i0Y5vUdWcM
CzGXc154x/njmZYApK5EYS9F1b94LOIrHfZgQHVIXmeojQnwEGevvjLPbleOnC9N
v4k0idgyEns=
=RMm3
-----END PGP SIGNATURE-----

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ace0a87f6d9709c561390f4cb8fcc3b6ddd82af8cddc6f6807fdfeff5aa51a4a
size 2579758

View File

@@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
iQJHBAABCgAxFiEEhQ4PyyeXiiU/kaG0oOq4k+ppXVgFAml7G3ITHG1pY2FmZXJA
YXBhY2hlLm9yZwAKCRCg6riT6mldWGqMD/44g7Ljod+suwjAab//CzeIzYT6ngiU
jhoouuI1rb+l2ZIHj205ut7zt3kyhmRjJfnEafyvAR3KqbEnTVqcyShn29RAa3Jq
9N8EdJI0nSQwtJPQWVIEpsH4dWDL1Wrt9Ug85sqXw+n7j/qHkXk09KGo00Z4hST2
e1+NZTX1eTgOft2qpBaVXpixnU+rZKM1JQnkq93WijO4DrdXbBkr2USAQxICWe2g
L9ehaRngzfWU75mC6Pr8DFaJxrZZsCR9pjrlxGSkiXU6s1ykcPAqU+pSs5LZ6zO1
LPsnyQFPYLt5BsjBG/XVpXUya1yjI0GleIYtm/hy4JMcgItebbQuziGO6UAQCGHN
OU8kcs1AWVYUqlIFbbb8vpoYG7sK2j4HT4ZqvAPLVHgDMrDdXzRPwNlA5IgohTMV
VtyN+jHt139aA/xtCIfaSZ+Tw3zI9WVAPfgIig9vgC5PslfEGEvOxRopzFkg4yf6
D2Vl/lhkYSz0kfkkUD7+VPQ4OswAbZ0OjfY7SV3sQXX6rypvyT5KDh13g3/oXN/t
xTC/PgLKHKPjqAt4+JBvD7haObOuBa7DOYKT0dcS9I1Rq007Kh49a2oJyU4YAWgO
rkVThrE91SeC1tluZ5pLDG5q4nPHaSPwx2dt/jK715DzmM1PigGR1FPCp8MFUMqI
u1ENPEUJ4WtgTg==
=ihHL
-----END PGP SIGNATURE-----

View File

@@ -1,8 +1,8 @@
Index: apache-libcloud-3.5.1/libcloud/compute/drivers/ec2.py
Index: apache_libcloud-3.9.0/libcloud/compute/drivers/ec2.py
===================================================================
--- apache-libcloud-3.5.1.orig/libcloud/compute/drivers/ec2.py
+++ apache-libcloud-3.5.1/libcloud/compute/drivers/ec2.py
@@ -1622,12 +1622,18 @@ class BaseEC2NodeDriver(NodeDriver):
--- apache_libcloud-3.9.0.orig/libcloud/compute/drivers/ec2.py
+++ apache_libcloud-3.9.0/libcloud/compute/drivers/ec2.py
@@ -1620,12 +1620,18 @@ class BaseEC2NodeDriver(NodeDriver):
on-demand price will be used.
:type ex_spot_max_price: ``float``
"""

40
fix-tests-python313.patch Normal file
View File

@@ -0,0 +1,40 @@
From c2bd6f4c096982d89a2e99114697b0ff1fa80176 Mon Sep 17 00:00:00 2001
From: Miguel Caballer <micafer1@upv.es>
Date: Tue, 17 Feb 2026 08:55:42 +0100
Subject: [PATCH] Fix error in py313
---
libcloud/test/common/test_openstack_identity.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: apache_libcloud-3.9.0/libcloud/test/common/test_openstack_identity.py
===================================================================
--- apache_libcloud-3.9.0.orig/libcloud/test/common/test_openstack_identity.py
+++ apache_libcloud-3.9.0/libcloud/test/common/test_openstack_identity.py
@@ -235,7 +235,7 @@ class OpenStackIdentityConnectionTestCas
osa.auth_token = None
osa.auth_token_expires = YESTERDAY
- mocked_auth_method.call_count = 0
+ mocked_auth_method.reset_mock()
self.assertEqual(mocked_auth_method.call_count, 0)
for i in range(0, count):
@@ -246,7 +246,7 @@ class OpenStackIdentityConnectionTestCas
# No force reauth, valid / non-expired token
osa.auth_token = None
- mocked_auth_method.call_count = 0
+ mocked_auth_method.reset_mock()
self.assertEqual(mocked_auth_method.call_count, 0)
for i in range(0, count):
@@ -264,7 +264,7 @@ class OpenStackIdentityConnectionTestCas
)
osa.auth_token = None
- mocked_auth_method.call_count = 0
+ mocked_auth_method.reset_mock()
self.assertEqual(mocked_auth_method.call_count, 0)
for i in range(0, count):

View File

@@ -1,8 +1,8 @@
Index: apache-libcloud-3.5.1/libcloud/compute/drivers/gce.py
Index: apache_libcloud-3.9.0/libcloud/compute/drivers/gce.py
===================================================================
--- apache-libcloud-3.5.1.orig/libcloud/compute/drivers/gce.py
+++ apache-libcloud-3.5.1/libcloud/compute/drivers/gce.py
@@ -1981,12 +1981,19 @@ class GCENodeDriver(NodeDriver):
--- apache_libcloud-3.9.0.orig/libcloud/compute/drivers/gce.py
+++ apache_libcloud-3.9.0/libcloud/compute/drivers/gce.py
@@ -2040,12 +2040,19 @@ class GCENodeDriver(NodeDriver):
"debian-cloud": ["debian-8", "debian-9", "debian-10"],
"opensuse-cloud": ["opensuse-leap"],
"rhel-cloud": ["rhel-6", "rhel-7", "rhel-8"],
@@ -23,7 +23,7 @@ Index: apache-libcloud-3.5.1/libcloud/compute/drivers/gce.py
"suse-manager-proxy-byos",
"suse-manager-server-byos",
],
@@ -1994,7 +2001,13 @@ class GCENodeDriver(NodeDriver):
@@ -2053,7 +2060,13 @@ class GCENodeDriver(NodeDriver):
"sles-12-sp2-sap",
"sles-12-sp3-sap",
"sles-12-sp4-sap",

View File

@@ -1,3 +1,64 @@
-------------------------------------------------------------------
Tue Feb 17 13:52:08 UTC 2026 - Daniel Garcia <daniel.garcia@suse.com>
- Update to 3.9.0
* Common
- Support for Python 3.9 which is EOL has been removed.
- Indicate we also support Python 3.12 (non beta) and Python 3.13.
- Support for Python 3.8 which is EOL has been removed.
- Support for Python 3.7 which is EOL has been removed.
- Types inheriting from ``libcloud.common.types.Type`` have been made hashable.
- [NTT CIS] Fix invalid comparison in the ``XmlListConfig.__init__()`` method.
- Update versions of build and packaging tools required to build the package.
* Compute
- [OpenStack] Add optional node port ID to attach the floating IP
in OpenStack ex_attach_floating_ip_to_node function.
- [OpenStack] Add metadata fields ``os_distro`` and ``os_version``
provided by OpenStack Image API (if set) to the ``extra`` field
of the OpenStack NodeImage.
- [LINODE] Add support for cloud-init metadata support to
create_node() Add new functions ``create_key_pair``,
``list_key_pairs``, and ``get_image``
- [Azure ARM] Add a new argument to destroy_node() to also delete
node's managed OS disk as part of the node's deletion.
- [ECS] Add VPC IP and Elastic IP to ECS node as private and public IP.
- [Azure ARM] When deleting a node, delete VM OS disk if it's a managed disk.
- [Azure ARM] Add ``ex_resize_node()`` method.
- [Equinix Metal] Fix ``list_nodes()`` method so it correctly
handles NodeSize.ram attribute in case TB is returned.
- [Equinix Metal] Deprecate facility API and replace it with metros location.
- [Equinix Metal] Remove all the methods for managing volumes and
volume snapshots. This functionality hasn't been supported on
the server side for many years already.
- [Amazon EC2] Update pricing and sizing data.
- [OpenStack] Add `is_default` and `tags` extra fields to the
OpenStack Network Object (`OpenStackNetwork`).
- [KubeVirt] Various improvements and fixes in the driver:
* Improve compatibility with the base NodeDriver class
* Support for deployment (`deploy_node()`)
* Support for general volume (disks) types that KubeVirt supports
* Add support for the `ex_template` parameter in `create_node()` method
* Various improvements in `_to_node()` related to node information parsing
* Improved test suite
* Code refactoring and improvements
- [Amazon S3] Add support for ``me-central-1`` region.
* Storage
- [Amazon S3] Add support for ``eu-south-1`` region.
- [Amazon S3] Add support for ``eu-west-3`` region.
* Other / Development
- Adopt uv for dependency management.
- pytest library used for running tests and microbenchmarks has
been upgraded to v8.1.
- Add a workaround so tests work with pytest >= 8.2. Also use
latest version of pytest for running tests.
- Drop upstreamed patches:
* support-pytest-8.2.patch
* support-pytest-8.patch
- New patch fix-tests-python313.patch to fix compatibility with latest
python3.13, bsc#1258223
-------------------------------------------------------------------
Tue Sep 3 04:49:42 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
@@ -15,7 +76,7 @@ Thu Jun 6 02:51:26 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
* Support running under pytest 8.2.x.
-------------------------------------------------------------------
Tue Sep 26 00:00:00 PM CEST 2023 - ecsosa <ecsos@opensuse.org>
Tue Sep 26 00:00:00 CEST 2023 - ecsosa <ecsos@opensuse.org>
- Update to 3.8.0
* Compute

View File

@@ -1910,3 +1910,62 @@ AQIFspCNd7aPsguzPwNmcrfrfM9VwjNP7P7YHjHeOA2Dj6KhvfN9A05/vXdX7aOL
xoCEep5WBCdnai/8Cwy6UfVroiULmbAPwzOKiA==
=1bMz
-----END PGP PUBLIC KEY BLOCK-----
pub rsa4096 2026-01-29 [SC]
850E0FCB27978A253F91A1B4A0EAB893EA695D58
uid [ absoluta ] Miguel Caballer (Apache account) <micafer@apache.org>
sig 3 A0EAB893EA695D58 2026-01-29 [autofirma]
sub rsa4096 2026-01-29 [E]
sig A0EAB893EA695D58 2026-01-29 [autofirma]
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
vjsK0wu+5WeIMraJXVyMsAbrIc0=
=3l6w
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -1,7 +1,7 @@
#
# spec file for package python-apache-libcloud
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-apache-libcloud
Version: 3.8.0
Version: 3.9.0
Release: 0
Summary: Abstraction over multiple cloud provider APIs
License: Apache-2.0
@@ -29,16 +29,15 @@ Source1: https://downloads.apache.org/libcloud/apache-libcloud-%{version}
Source2: https://www.apache.org/dist/libcloud/KEYS#/%{name}.keyring
Patch1: gce_image_projects.patch
Patch2: ec2_create_node.patch
# PATCH-FIX-UPSTREAM gh#apache/libcloud#1994
Patch3: support-pytest-8.patch
# PATCH-FIX-UPSTREAM gh#apache/libcloud#2033
Patch4: support-pytest-8.2.patch
# PATCH-FIX-UPSTREAM gh#apache/libcloud#2121
Patch3: fix-tests-python313.patch
BuildRequires: %{python_module base >= 3.7}
BuildRequires: %{python_module fasteners}
BuildRequires: %{python_module libvirt-python}
BuildRequires: %{python_module paramiko}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module pyOpenSSL}
BuildRequires: %{python_module pytest-benchmark}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module requests-mock}
BuildRequires: %{python_module setuptools}
@@ -59,10 +58,8 @@ Apache Libcloud is a standard Python library that abstracts away
differences among multiple cloud provider APIs.
%prep
%autosetup -p1 -n apache-libcloud-%{version}
sed -i '/^#!/d' demos/gce_demo.py
chmod a-x demos/gce_demo.py
# Setup tests
%autosetup -p1 -n apache_libcloud-%{version}
# # Setup tests
cp libcloud/test/secrets.py-dist libcloud/test/secrets.py
%build
@@ -100,7 +97,7 @@ donttest+=" or test_init_once_and_debug_mode"
%files %{python_files}
%license LICENSE
%doc CHANGES.rst README.rst demos/ example_*.py
%doc CHANGES.rst README.rst example_*.py
%{python_sitelib}/libcloud
%{python_sitelib}/apache_libcloud-%{version}.dist-info

View File

@@ -1,39 +0,0 @@
From 44e923662205f2a2413fadb23715dc2934bff625 Mon Sep 17 00:00:00 2001
From: Steve Kowalik <steven@wedontsleep.org>
Date: Tue, 3 Sep 2024 14:30:51 +1000
Subject: [PATCH] Only call super() during MockHttp if required
With pytest 8.2 and above, any class that contains classes is collected,
which means they are instantiated, which MockHttp's superclasses do not
accept, since they require keyword arguments. To work around this, only
call the superclass's __init__ method if we are passed kwargs.
---
libcloud/test/__init__.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libcloud/test/__init__.py b/libcloud/test/__init__.py
index d45c82c84d..1cc595f685 100644
--- a/libcloud/test/__init__.py
+++ b/libcloud/test/__init__.py
@@ -87,7 +87,7 @@ def read(self, chunk_size=None):
return StringIO.read(self)
-class MockHttp(LibcloudConnection):
+class MockHttp(LibcloudConnection, unittest.TestCase):
"""
A mock HTTP client/server suitable for testing purposes. This replaces
`HTTPConnection` by implementing its API and returning a mock response.
@@ -108,7 +108,11 @@ def __init__(self, *args, **kwargs):
# within a response
if isinstance(self, unittest.TestCase):
unittest.TestCase.__init__(self, "__init__")
- super().__init__(*args, **kwargs)
+ # When this class is collected, it is instantiated with no arguments,
+ # which breaks any superclasses that expect arguments, so only
+ # do so if we were passed any keyword arguments.
+ if kwargs:
+ super().__init__(*args, **kwargs)
def _get_request(self, method, url, body=None, headers=None):
# Find a method we can use for this request

View File

@@ -1,440 +0,0 @@
From 6a646d0c3fd3c1d33183bb338235aaa43f86d1f8 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 26 Feb 2024 17:44:37 +0000
Subject: [PATCH 01/15] Bump pytest from 7.4.0 to 8.0.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.0 to 8.0.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.0...8.0.2)
---
updated-dependencies:
- dependency-name: pytest
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
---
requirements-tests.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: apache-libcloud-3.8.0/requirements-tests.txt
===================================================================
--- apache-libcloud-3.8.0.orig/requirements-tests.txt
+++ apache-libcloud-3.8.0/requirements-tests.txt
@@ -1,7 +1,7 @@
coverage[toml]==7.2.7; python_version >= '3.8'
requests>=2.31.0
requests_mock==1.11.0
-pytest==7.4.0
+pytest==8.0.2
pytest-xdist==3.3.1
pytest-timeout==2.1.0
pytest-benchmark[histogram]==4.0.0
Index: apache-libcloud-3.8.0/tox.ini
===================================================================
--- apache-libcloud-3.8.0.orig/tox.ini
+++ apache-libcloud-3.8.0/tox.ini
@@ -39,8 +39,11 @@ setenv =
# To avoid per-test function process safety issues we run all tests in a single
# file in the same worker process.
# for pytest-xdist, we want to distribute tests by file aka --dist loadfile
+# Tests which are not safe to run in paralell are marked with "serial" tag
+# and run separately at the end
commands = cp libcloud/test/secrets.py-dist libcloud/test/secrets.py
- pytest --color=yes -rsx -vvv --capture=tee-sys -o log_cli=True --durations=10 --timeout=15 -n auto --dist loadfile --ignore libcloud/test/benchmarks/ --ignore-glob "*test_list_objects_filtering_performance*"
+ pytest --color=yes -rsx -vvv --capture=tee-sys -o log_cli=True --durations=10 --timeout=15 -n auto --dist loadfile --ignore libcloud/test/benchmarks/ --ignore-glob "*test_list_objects_filtering_performance*" -m "not serial"
+ pytest --color=yes -rsx -vvv --capture=tee-sys -o log_cli=True --durations=10 --timeout=15 --ignore libcloud/test/benchmarks/ --ignore-glob "*test_list_objects_filtering_performance*" -m "serial"
[testenv:py3.6-dist]
# Verify library installs without any dependencies when using python setup.py
Index: apache-libcloud-3.8.0/libcloud/test/test_init.py
===================================================================
--- apache-libcloud-3.8.0.orig/libcloud/test/test_init.py
+++ apache-libcloud-3.8.0/libcloud/test/test_init.py
@@ -19,6 +19,8 @@ import logging
import tempfile
from unittest.mock import patch
+import pytest
+
import libcloud
from libcloud import _init_once
from libcloud.base import DriverTypeNotFoundError
@@ -38,6 +40,7 @@ class TestUtils(unittest.TestCase):
if "LIBCLOUD_DEBUG" in os.environ:
del os.environ["LIBCLOUD_DEBUG"]
+ @pytest.mark.serial
def test_init_once_and_debug_mode(self):
if have_paramiko:
paramiko_logger = logging.getLogger("paramiko")
Index: apache-libcloud-3.8.0/libcloud/test/common/test_digitalocean_v2.py
===================================================================
--- apache-libcloud-3.8.0.orig/libcloud/test/common/test_digitalocean_v2.py
+++ apache-libcloud-3.8.0/libcloud/test/common/test_digitalocean_v2.py
@@ -15,22 +15,28 @@
import sys
import unittest
+from libcloud.http import LibcloudConnection
from libcloud.test import MockHttp, LibcloudTestCase
from libcloud.utils.py3 import httplib
from libcloud.common.types import InvalidCredsError
from libcloud.test.secrets import DIGITALOCEAN_v2_PARAMS
from libcloud.test.file_fixtures import FileFixtures
-from libcloud.common.digitalocean import DigitalOceanBaseDriver
+from libcloud.common.digitalocean import DigitalOceanBaseDriver, DigitalOcean_v2_BaseDriver
class DigitalOceanTests(LibcloudTestCase):
def setUp(self):
- DigitalOceanBaseDriver.connectionCls.conn_class = DigitalOceanMockHttp
- DigitalOceanMockHttp.type = None
+ DigitalOceanBaseDriver.connectionCls.conn_class = DigitalOceanCommonMockHttp
+ DigitalOcean_v2_BaseDriver.connectionCls.conn_class = DigitalOceanCommonMockHttp
+ DigitalOceanCommonMockHttp.type = None
self.driver = DigitalOceanBaseDriver(*DIGITALOCEAN_v2_PARAMS)
+ def tearDown(self):
+ LibcloudConnection.type = None
+ DigitalOceanCommonMockHttp.type = None
+
def test_authentication(self):
- DigitalOceanMockHttp.type = "UNAUTHORIZED"
+ DigitalOceanCommonMockHttp.type = "UNAUTHORIZED"
self.assertRaises(InvalidCredsError, self.driver.ex_account_info)
def test_ex_account_info(self):
@@ -51,13 +57,13 @@ class DigitalOceanTests(LibcloudTestCase
self.assertEqual(action["type"], "power_on")
def test__paginated_request(self):
- DigitalOceanMockHttp.type = "page_1"
+ DigitalOceanCommonMockHttp.type = "page_1"
actions = self.driver._paginated_request("/v2/actions", "actions")
self.assertEqual(actions[0]["id"], 12345671)
self.assertEqual(actions[0]["status"], "completed")
-class DigitalOceanMockHttp(MockHttp):
+class DigitalOceanCommonMockHttp(MockHttp):
fixtures = FileFixtures("common", "digitalocean")
response = {
Index: apache-libcloud-3.8.0/libcloud/test/compute/test_digitalocean_v2.py
===================================================================
--- apache-libcloud-3.8.0.orig/libcloud/test/compute/test_digitalocean_v2.py
+++ apache-libcloud-3.8.0/libcloud/test/compute/test_digitalocean_v2.py
@@ -16,6 +16,7 @@ import sys
import unittest
from datetime import datetime
+from libcloud.http import LibcloudConnection
from libcloud.test import MockHttp, LibcloudTestCase
from libcloud.utils.py3 import httplib, assertRaisesRegex
from libcloud.common.types import InvalidCredsError
@@ -23,8 +24,15 @@ from libcloud.compute.base import NodeIm
from libcloud.test.secrets import DIGITALOCEAN_v1_PARAMS, DIGITALOCEAN_v2_PARAMS
from libcloud.utils.iso8601 import UTC
from libcloud.test.file_fixtures import ComputeFileFixtures
-from libcloud.common.digitalocean import DigitalOcean_v1_Error
-from libcloud.compute.drivers.digitalocean import DigitalOceanNodeDriver
+from libcloud.common.digitalocean import (
+ DigitalOcean_v1_Error,
+ DigitalOceanBaseDriver,
+ DigitalOcean_v2_BaseDriver,
+)
+from libcloud.compute.drivers.digitalocean import (
+ DigitalOceanNodeDriver,
+ DigitalOcean_v2_NodeDriver,
+)
try:
import simplejson as json
@@ -35,10 +43,17 @@ except ImportError:
# class DigitalOceanTests(unittest.TestCase, TestCaseMixin):
class DigitalOcean_v2_Tests(LibcloudTestCase):
def setUp(self):
- DigitalOceanNodeDriver.connectionCls.conn_class = DigitalOceanMockHttp
- DigitalOceanMockHttp.type = None
+ DigitalOceanBaseDriver.connectionCls.conn_class = DigitalOceanComputeMockHttp
+ DigitalOcean_v2_BaseDriver.connectionCls.conn_class = DigitalOceanComputeMockHttp
+ DigitalOceanNodeDriver.connectionCls.conn_class = DigitalOceanComputeMockHttp
+ DigitalOcean_v2_NodeDriver.connectionCls.conn_class = DigitalOceanComputeMockHttp
+ DigitalOceanComputeMockHttp.type = None
self.driver = DigitalOceanNodeDriver(*DIGITALOCEAN_v2_PARAMS)
+ def tearDown(self):
+ LibcloudConnection.type = None
+ DigitalOceanComputeMockHttp.type = None
+
def test_v1_Error(self):
self.assertRaises(
DigitalOcean_v1_Error,
@@ -56,7 +71,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
)
def test_authentication(self):
- DigitalOceanMockHttp.type = "UNAUTHORIZED"
+ DigitalOceanComputeMockHttp.type = "UNAUTHORIZED"
self.assertRaises(InvalidCredsError, self.driver.list_nodes)
def test_list_images_success(self):
@@ -128,7 +143,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
size = self.driver.list_sizes()[0]
location = self.driver.list_locations()[0]
- DigitalOceanMockHttp.type = "INVALID_IMAGE"
+ DigitalOceanComputeMockHttp.type = "INVALID_IMAGE"
expected_msg = (
r"You specified an invalid image for Droplet creation."
+ r" \(code: (404|HTTPStatus.NOT_FOUND)\)"
@@ -146,13 +161,13 @@ class DigitalOcean_v2_Tests(LibcloudTest
def test_reboot_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "REBOOT"
+ DigitalOceanComputeMockHttp.type = "REBOOT"
result = self.driver.reboot_node(node)
self.assertTrue(result)
def test_create_image_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "SNAPSHOT"
+ DigitalOceanComputeMockHttp.type = "SNAPSHOT"
result = self.driver.create_image(node, "My snapshot")
self.assertTrue(result)
@@ -164,62 +179,62 @@ class DigitalOcean_v2_Tests(LibcloudTest
def test_delete_image_success(self):
image = self.driver.get_image(12345)
- DigitalOceanMockHttp.type = "DESTROY"
+ DigitalOceanComputeMockHttp.type = "DESTROY"
result = self.driver.delete_image(image)
self.assertTrue(result)
def test_ex_power_on_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "POWERON"
+ DigitalOceanComputeMockHttp.type = "POWERON"
result = self.driver.ex_power_on_node(node)
self.assertTrue(result)
def test_ex_shutdown_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "SHUTDOWN"
+ DigitalOceanComputeMockHttp.type = "SHUTDOWN"
result = self.driver.ex_shutdown_node(node)
self.assertTrue(result)
def test_ex_hard_reboot_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "POWERCYCLE"
+ DigitalOceanComputeMockHttp.type = "POWERCYCLE"
result = self.driver.ex_hard_reboot(node)
self.assertTrue(result)
def test_ex_rebuild_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "REBUILD"
+ DigitalOceanComputeMockHttp.type = "REBUILD"
result = self.driver.ex_rebuild_node(node)
self.assertTrue(result)
def test_ex_resize_node_success(self):
node = self.driver.list_nodes()[0]
size = self.driver.list_sizes()[0]
- DigitalOceanMockHttp.type = "RESIZE"
+ DigitalOceanComputeMockHttp.type = "RESIZE"
result = self.driver.ex_resize_node(node, size)
self.assertTrue(result)
def test_destroy_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "DESTROY"
+ DigitalOceanComputeMockHttp.type = "DESTROY"
result = self.driver.destroy_node(node)
self.assertTrue(result)
def test_ex_change_kernel_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "KERNELCHANGE"
+ DigitalOceanComputeMockHttp.type = "KERNELCHANGE"
result = self.driver.ex_change_kernel(node, 7515)
self.assertTrue(result)
def test_ex_enable_ipv6_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "ENABLEIPV6"
+ DigitalOceanComputeMockHttp.type = "ENABLEIPV6"
result = self.driver.ex_enable_ipv6(node)
self.assertTrue(result)
def test_ex_rename_node_success(self):
node = self.driver.list_nodes()[0]
- DigitalOceanMockHttp.type = "RENAME"
+ DigitalOceanComputeMockHttp.type = "RENAME"
result = self.driver.ex_rename_node(node, "fedora helios")
self.assertTrue(result)
@@ -231,7 +246,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
self.assertEqual(keys[0].public_key, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQDGk5 example")
def test_create_key_pair(self):
- DigitalOceanMockHttp.type = "CREATE"
+ DigitalOceanComputeMockHttp.type = "CREATE"
key = self.driver.create_key_pair(
name="test1", public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQsxRiUKn example"
)
@@ -250,7 +265,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
self.assertEqual(nodes[0]["size_slug"], "s-1vcpu-1gb")
def test__paginated_request_two_pages(self):
- DigitalOceanMockHttp.type = "PAGE_ONE"
+ DigitalOceanComputeMockHttp.type = "PAGE_ONE"
nodes = self.driver._paginated_request("/v2/droplets", "droplets")
self.assertEqual(len(nodes), 2)
@@ -264,13 +279,13 @@ class DigitalOcean_v2_Tests(LibcloudTest
self.assertEqual(volume.driver, self.driver)
def test_list_volumes_empty(self):
- DigitalOceanMockHttp.type = "EMPTY"
+ DigitalOceanComputeMockHttp.type = "EMPTY"
volumes = self.driver.list_volumes()
self.assertEqual(len(volumes), 0)
def test_create_volume(self):
nyc1 = [r for r in self.driver.list_locations() if r.id == "nyc1"][0]
- DigitalOceanMockHttp.type = "CREATE"
+ DigitalOceanComputeMockHttp.type = "CREATE"
volume = self.driver.create_volume(4, "example", nyc1)
self.assertEqual(volume.id, "62766883-2c28-11e6-b8e6-000f53306ae1")
self.assertEqual(volume.name, "example")
@@ -280,19 +295,19 @@ class DigitalOcean_v2_Tests(LibcloudTest
def test_attach_volume(self):
node = self.driver.list_nodes()[0]
volume = self.driver.list_volumes()[0]
- DigitalOceanMockHttp.type = "ATTACH"
+ DigitalOceanComputeMockHttp.type = "ATTACH"
resp = self.driver.attach_volume(node, volume)
self.assertTrue(resp)
def test_detach_volume(self):
volume = self.driver.list_volumes()[0]
- DigitalOceanMockHttp.type = "DETACH"
+ DigitalOceanComputeMockHttp.type = "DETACH"
resp = self.driver.detach_volume(volume)
self.assertTrue(resp)
def test_destroy_volume(self):
volume = self.driver.list_volumes()[0]
- DigitalOceanMockHttp.type = "DESTROY"
+ DigitalOceanComputeMockHttp.type = "DESTROY"
resp = self.driver.destroy_volume(volume)
self.assertTrue(resp)
@@ -307,7 +322,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
def test_create_volume_snapshot(self):
volume = self.driver.list_volumes()[0]
- DigitalOceanMockHttp.type = "CREATE"
+ DigitalOceanComputeMockHttp.type = "CREATE"
snapshot = self.driver.create_volume_snapshot(volume, "test-snapshot")
self.assertEqual(snapshot.id, "c0def940-9324-11e6-9a56-000f533176b1")
self.assertEqual(snapshot.name, "test-snapshot")
@@ -316,7 +331,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
def test_delete_volume_snapshot(self):
volume = self.driver.list_volumes()[0]
snapshot = self.driver.list_volume_snapshots(volume)[0]
- DigitalOceanMockHttp.type = "DELETE"
+ DigitalOceanComputeMockHttp.type = "DELETE"
result = self.driver.delete_volume_snapshot(snapshot)
self.assertTrue(result)
@@ -396,7 +411,7 @@ class DigitalOcean_v2_Tests(LibcloudTest
self.assertTrue(ret)
-class DigitalOceanMockHttp(MockHttp):
+class DigitalOceanComputeMockHttp(MockHttp):
fixtures = ComputeFileFixtures("digitalocean_v2")
def _v2_regions(self, method, url, body, headers):
Index: apache-libcloud-3.8.0/libcloud/test/dns/test_digitalocean.py
===================================================================
--- apache-libcloud-3.8.0.orig/libcloud/test/dns/test_digitalocean.py
+++ apache-libcloud-3.8.0/libcloud/test/dns/test_digitalocean.py
@@ -15,20 +15,28 @@
import sys
import unittest
+from libcloud.http import LibcloudConnection
from libcloud.test import MockHttp, LibcloudTestCase
from libcloud.dns.types import RecordType
from libcloud.utils.py3 import httplib
from libcloud.test.secrets import DIGITALOCEAN_v2_PARAMS
from libcloud.test.file_fixtures import DNSFileFixtures
+from libcloud.common.digitalocean import DigitalOceanBaseDriver, DigitalOcean_v2_BaseDriver
from libcloud.dns.drivers.digitalocean import DigitalOceanDNSDriver
class DigitalOceanDNSTests(LibcloudTestCase):
def setUp(self):
+ DigitalOceanBaseDriver.connectionCls.conn_class = DigitalOceanDNSMockHttp
+ DigitalOcean_v2_BaseDriver.connectionCls.conn_class = DigitalOceanDNSMockHttp
DigitalOceanDNSDriver.connectionCls.conn_class = DigitalOceanDNSMockHttp
DigitalOceanDNSMockHttp.type = None
self.driver = DigitalOceanDNSDriver(*DIGITALOCEAN_v2_PARAMS)
+ def tearDown(self):
+ LibcloudConnection.type = None
+ DigitalOceanDNSMockHttp.type = None
+
def test_list_zones(self):
zones = self.driver.list_zones()
self.assertTrue(len(zones) >= 1)
Index: apache-libcloud-3.8.0/libcloud/test/__init__.py
===================================================================
--- apache-libcloud-3.8.0.orig/libcloud/test/__init__.py
+++ apache-libcloud-3.8.0/libcloud/test/__init__.py
@@ -205,7 +205,7 @@ class MockHttp(LibcloudConnection):
) # Python 3.7 no longer quotes ~
if type:
- meth_name = "{}_{}".format(meth_name, self.type)
+ meth_name = "{}_{}".format(meth_name, type)
if use_param and use_param in qs:
param = qs[use_param][0].replace(".", "_").replace("-", "_")
Index: apache-libcloud-3.8.0/CHANGES.rst
===================================================================
--- apache-libcloud-3.8.0.orig/CHANGES.rst
+++ apache-libcloud-3.8.0/CHANGES.rst
@@ -1,6 +1,22 @@
Changelog
=========
+Other / Development
+~~~~~--------------
+
+- pytest library used for running tests and microbenchmarks has been upgraded to
+ v8.1.
+
+ Changes in the pytest test discovery and collection mechanism and ordering
+ have uncovered some race conditions and cross test pollution which has been
+ addressed.
+
+ Now all the tests are passing, but it's possible that there are still some
+ race conditions hiding which many only pop up in the future (since we run
+ tests in parallel and order in which they run is not fully deterministic).
+ (#1994)
+ [Tomaz Muraus - @Kami]
+
Changes in Apache Libcloud 3.8.0
--------------------------------