Skip to content

Commit f622665

Browse files
authored
Merge pull request #791 from gerrod3/370-compat
Declare compatibility with pulpcore 3.70
2 parents 86f5710 + c1a84bb commit f622665

File tree

12 files changed

+66
-73
lines changed

12 files changed

+66
-73
lines changed

.github/workflows/scripts/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ minio_access_key: "'$MINIO_ACCESS_KEY'"\
9797
minio_secret_key: "'$MINIO_SECRET_KEY'"\
9898
pulp_scenario_settings: {"domain_enabled": true}\
9999
pulp_scenario_env: {}\
100-
test_storages_compat_layer: false\
100+
test_storages_compat_layer: true\
101101
' vars/main.yaml
102102
export PULP_API_ROOT="/rerouted/djnd/"
103103
fi

CHANGES/+pulpcore-3.70.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added pulpcore 3.70 compatibility

pulp_python/app/fields.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

pulp_python/app/pypi/serializers.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from rest_framework import serializers
55
from pulp_python.app.utils import DIST_EXTENSIONS
6-
from pulp_python.app import fields
76
from pulpcore.plugin.models import Artifact
87
from pulpcore.plugin.util import get_domain
98
from django.db.utils import IntegrityError
@@ -29,9 +28,9 @@ class PackageMetadataSerializer(serializers.Serializer):
2928
"""
3029

3130
last_serial = serializers.IntegerField(help_text=_("Cache value from last PyPI sync"))
32-
info = fields.JSONObjectField(help_text=_("Core metadata of the package"))
33-
releases = fields.JSONObjectField(help_text=_("List of all the releases of the package"))
34-
urls = fields.JSONObjectField()
31+
info = serializers.JSONField(help_text=_("Core metadata of the package"))
32+
releases = serializers.JSONField(help_text=_("List of all the releases of the package"))
33+
urls = serializers.JSONField()
3534

3635

3736
class PackageUploadSerializer(serializers.Serializer):

pulp_python/app/serializers.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from pulpcore.plugin.util import get_domain
99

1010
from pulp_python.app import models as python_models
11-
from pulp_python.app import fields
1211
from pulp_python.app.utils import artifact_to_python_content_data
1312

1413

@@ -158,7 +157,7 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
158157
required=False, allow_blank=True,
159158
help_text=_('A browsable URL for the project and a label for it, separated by a comma.')
160159
)
161-
project_urls = fields.JSONObjectField(
160+
project_urls = serializers.JSONField(
162161
required=False, default=dict,
163162
help_text=_('A dictionary of labels and URLs for the project.')
164163
)
@@ -171,28 +170,28 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
171170
required=False, allow_blank=True,
172171
help_text=_('Field to specify the OS and CPU for which the binary package was compiled. ')
173172
)
174-
requires_dist = fields.JSONObjectField(
173+
requires_dist = serializers.JSONField(
175174
required=False, default=list,
176175
help_text=_('A JSON list containing names of some other distutils project '
177176
'required by this distribution.')
178177
)
179-
provides_dist = fields.JSONObjectField(
178+
provides_dist = serializers.JSONField(
180179
required=False, default=list,
181180
help_text=_('A JSON list containing names of a Distutils project which is contained'
182181
' within this distribution.')
183182
)
184-
obsoletes_dist = fields.JSONObjectField(
183+
obsoletes_dist = serializers.JSONField(
185184
required=False, default=list,
186185
help_text=_('A JSON list containing names of a distutils project\'s distribution which '
187186
'this distribution renders obsolete, meaning that the two projects should not '
188187
'be installed at the same time.')
189188
)
190-
requires_external = fields.JSONObjectField(
189+
requires_external = serializers.JSONField(
191190
required=False, default=list,
192191
help_text=_('A JSON list containing some dependency in the system that the distribution '
193192
'is to be used.')
194193
)
195-
classifiers = fields.JSONObjectField(
194+
classifiers = serializers.JSONField(
196195
required=False, default=list,
197196
help_text=_('A JSON list containing classification values for a Python package.')
198197
)

pulp_python/pytest_plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def _download_python_file(relative_path, url):
145145
file_path = tmp_path / relative_path
146146
with open(file_path, mode="wb") as f:
147147
f.write(http_get(url))
148-
return file_path
148+
return str(file_path)
149149

150150
yield _download_python_file
151151

pulp_python/tests/functional/api/test_crud_content_unit.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,23 @@ def test_content_crud(
2626
content_body = {"relative_path": PYTHON_EGG_FILENAME, "artifact": artifact.pulp_href}
2727
response = python_bindings.ContentPackagesApi.create(**content_body)
2828
task = monitor_task(response.task)
29-
content = python_bindings.ContentPackagesApi.read(task.created_resources[0]).to_dict()
29+
content = python_bindings.ContentPackagesApi.read(task.created_resources[0])
3030
for k, v in PYTHON_PACKAGE_DATA.items():
31-
assert content[k] == v
31+
assert getattr(content, k) == v
3232

3333
# Test read
34-
result = python_bindings.ContentPackagesApi.list(filename=content["filename"])
34+
result = python_bindings.ContentPackagesApi.list(filename=content.filename)
3535
assert result.count == 1
36-
assert result.results[0].to_dict() == content
36+
assert result.results[0] == content
3737

3838
# Test partial update
3939
with pytest.raises(AttributeError) as e:
40-
python_bindings.ContentPackagesApi.partial_update(content["pulp_href"], {"filename": "te"})
40+
python_bindings.ContentPackagesApi.partial_update(content.pulp_href, {"filename": "te"})
4141
assert "object has no attribute 'partial_update'" in e.value.args[0]
4242

4343
# Test delete
4444
with pytest.raises(AttributeError) as e:
45-
python_bindings.ContentPackagesApi.delete(content["pulp_href"])
45+
python_bindings.ContentPackagesApi.delete(content.pulp_href)
4646
assert "object has no attribute 'delete'" in e.value.args[0]
4747

4848
monitor_task(pulpcore_bindings.OrphansCleanupApi.cleanup({"orphan_protection_time": 0}).task)
@@ -51,9 +51,9 @@ def test_content_crud(
5151
content_body = {"relative_path": PYTHON_EGG_FILENAME, "file": python_file}
5252
response = python_bindings.ContentPackagesApi.create(**content_body)
5353
task = monitor_task(response.task)
54-
content = python_bindings.ContentPackagesApi.read(task.created_resources[0]).to_dict()
54+
content = python_bindings.ContentPackagesApi.read(task.created_resources[0])
5555
for k, v in PYTHON_PACKAGE_DATA.items():
56-
assert content[k] == v
56+
assert getattr(content, k) == v
5757

5858
monitor_task(pulpcore_bindings.OrphansCleanupApi.cleanup({"orphan_protection_time": 0}).task)
5959

@@ -65,36 +65,36 @@ def test_content_crud(
6565
content_search = python_bindings.ContentPackagesApi.list(
6666
repository_version_added=task.created_resources[0]
6767
)
68-
content = python_bindings.ContentPackagesApi.read(content_search.results[0].pulp_href).to_dict()
68+
content = python_bindings.ContentPackagesApi.read(content_search.results[0].pulp_href)
6969
for k, v in PYTHON_PACKAGE_DATA.items():
70-
assert content[k] == v
70+
assert getattr(content, k) == v
7171

7272
# Test duplicate upload
7373
content_body = {"relative_path": PYTHON_EGG_FILENAME, "file": python_file}
7474
response = python_bindings.ContentPackagesApi.create(**content_body)
7575
task = monitor_task(response.task)
76-
assert task.created_resources[0] == content["pulp_href"]
76+
assert task.created_resources[0] == content.pulp_href
7777

7878
# Test upload same filename w/ different artifact
7979
second_python_url = urljoin(urljoin(PYTHON_FIXTURES_URL, "packages/"), "aiohttp-3.3.0.tar.gz")
8080
second_python_file = download_python_file("aiohttp-3.3.0.tar.gz", second_python_url)
8181
content_body = {"relative_path": PYTHON_EGG_FILENAME, "file": second_python_file}
8282
response = python_bindings.ContentPackagesApi.create(**content_body)
8383
task = monitor_task(response.task)
84-
content2 = python_bindings.ContentPackagesApi.read(task.created_resources[0]).to_dict()
85-
assert content2["pulp_href"] != content["pulp_href"]
84+
content2 = python_bindings.ContentPackagesApi.read(task.created_resources[0])
85+
assert content2.pulp_href != content.pulp_href
8686

8787
# Test upload same filename w/ different artifacts in same repo
8888
# repo already has EGG_FILENAME w/ EGG_ARTIFACT, not upload EGG_FILENAME w/ AIO_ARTIFACT
8989
# and see that repo will only have the second content unit inside after upload
9090
response = python_bindings.ContentPackagesApi.create(repository=repo.pulp_href, **content_body)
9191
task = monitor_task(response.task)
9292
assert len(task.created_resources) == 2
93-
assert content2["pulp_href"] in task.created_resources
93+
assert content2.pulp_href in task.created_resources
9494
repo_ver2 = task.created_resources[0]
9595
content_list = python_bindings.ContentPackagesApi.list(repository_version=repo_ver2)
9696
assert content_list.count == 1
97-
assert content_list.results[0].pulp_href == content2["pulp_href"]
97+
assert content_list.results[0].pulp_href == content2.pulp_href
9898

9999
# Test upload w/ mismatched sha256
100100
# If we don't perform orphan cleanup here, the upload will fail with a different error :hmm:

pulp_python/tests/functional/api/test_crud_remotes.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414
@pytest.mark.parametrize("kwargs", [{}, {"policy": "on_demand"}])
1515
def test_remote_from_bandersnatch_config(kwargs, python_bindings, add_to_cleanup, tmp_path):
1616
"""Verify whether it's possible to create a remote from a Bandersnatch config."""
17-
filename = tmp_path / "bandersnatch.conf"
17+
filename = str(tmp_path / "bandersnatch.conf")
1818
with open(filename, mode="wb") as config:
1919
config.write(BANDERSNATCH_CONF)
2020
config.flush()
2121
name = str(uuid.uuid4())
22-
remote = python_bindings.RemotesPythonApi.from_bandersnatch(filename, name, **kwargs).to_dict()
23-
add_to_cleanup(python_bindings.RemotesPythonApi, remote["pulp_href"])
22+
remote = python_bindings.RemotesPythonApi.from_bandersnatch(filename, name, **kwargs)
23+
add_to_cleanup(python_bindings.RemotesPythonApi, remote.pulp_href)
2424
expected = _gen_expected_remote_body(name, **kwargs)
2525
for key, val in expected.items():
26-
assert remote[key] == val
26+
assert getattr(remote, key) == val
2727

2828

2929
@pytest.mark.parallel
@@ -40,16 +40,18 @@ def test_remote_default_policy(python_bindings, gen_object_with_cleanup, monitor
4040

4141

4242
@pytest.mark.parallel
43-
def test_remote_invalid_project_specifier(python_bindings):
43+
def test_remote_invalid_project_specifier(python_bindings, has_pulp_plugin):
4444
"""Test that creating a remote with an invalid project specifier fails."""
4545
# Test an include specifier without a "name" field.
4646
body = {
4747
"name": str(uuid.uuid4()),
4848
"url": "https://test",
4949
"includes": PYTHON_INVALID_SPECIFIER_NO_NAME,
5050
}
51-
with pytest.raises(python_bindings.ApiException):
52-
python_bindings.RemotesPythonApi.create(body)
51+
# Pydantic addition to bindings in 3.70 prevent this test from working
52+
if has_pulp_plugin("core", max="3.70"):
53+
with pytest.raises(python_bindings.ApiException):
54+
python_bindings.RemotesPythonApi.create(body)
5355

5456
# Test an include specifier with an invalid "version_specifier" field value.
5557
body["includes"] = PYTHON_INVALID_SPECIFIER_BAD_VERSION
@@ -59,8 +61,9 @@ def test_remote_invalid_project_specifier(python_bindings):
5961
# Test an exclude specifier without a "name" field.
6062
body.pop("includes")
6163
body["excludes"] = PYTHON_INVALID_SPECIFIER_NO_NAME
62-
with pytest.raises(python_bindings.ApiException):
63-
python_bindings.RemotesPythonApi.create(body)
64+
if has_pulp_plugin("core", max="3.70"):
65+
with pytest.raises(python_bindings.ApiException):
66+
python_bindings.RemotesPythonApi.create(body)
6467

6568
# Test an exclude specifier with an invalid "version_specifier" field value.
6669
body["excludes"] = PYTHON_INVALID_SPECIFIER_BAD_VERSION
@@ -95,14 +98,17 @@ def test_remote_version_specifier(python_bindings, add_to_cleanup):
9598

9699

97100
@pytest.mark.parallel
98-
def test_remote_update_invalid_project_specifier(python_bindings, python_remote_factory):
101+
def test_remote_update_invalid_project_specifier(
102+
python_bindings, python_remote_factory, has_pulp_plugin
103+
):
99104
"""Test that updating a remote with an invalid project specifier fails non-destructively."""
100105
remote = python_remote_factory()
101106

102107
# Test an include specifier without a "name" field.
103108
body = {"includes": PYTHON_INVALID_SPECIFIER_NO_NAME}
104-
with pytest.raises(python_bindings.ApiException):
105-
python_bindings.RemotesPythonApi.partial_update(remote.pulp_href, body)
109+
if has_pulp_plugin("core", max="3.70"):
110+
with pytest.raises(python_bindings.ApiException):
111+
python_bindings.RemotesPythonApi.partial_update(remote.pulp_href, body)
106112

107113
# Test an include specifier with an invalid "version_specifier" field value.
108114
body = {"includes": PYTHON_INVALID_SPECIFIER_BAD_VERSION}
@@ -111,8 +117,9 @@ def test_remote_update_invalid_project_specifier(python_bindings, python_remote_
111117

112118
# Test an exclude specifier without a "name" field.
113119
body = {"excludes": PYTHON_INVALID_SPECIFIER_NO_NAME}
114-
with pytest.raises(python_bindings.ApiException):
115-
python_bindings.RemotesPythonApi.partial_update(remote.pulp_href, body)
120+
if has_pulp_plugin("core", max="3.70"):
121+
with pytest.raises(python_bindings.ApiException):
122+
python_bindings.RemotesPythonApi.partial_update(remote.pulp_href, body)
116123

117124
# Test an exclude specifier with an invalid "version_specifier" field value.
118125
body = {"excludes": PYTHON_INVALID_SPECIFIER_BAD_VERSION}

pulp_python/tests/functional/api/test_domains.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pulpcore.app import settings
77

88
from pulp_python.tests.functional.constants import (
9-
PYTHON_URL,
109
PYTHON_EGG_FILENAME,
1110
PYTHON_SM_PROJECT_SPECIFIER,
1211
PYTHON_SM_PACKAGE_COUNT,
@@ -82,14 +81,6 @@ def test_domain_object_creation(
8281
}
8382

8483

85-
@pytest.fixture
86-
def python_file(tmp_path, http_get):
87-
filename = tmp_path / PYTHON_EGG_FILENAME
88-
with open(filename, mode="wb") as f:
89-
f.write(http_get(PYTHON_URL))
90-
yield filename
91-
92-
9384
@pytest.mark.parallel
9485
def test_domain_content_upload(
9586
domain_factory,

pulp_python/tests/functional/api/test_rbac.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import pytest
22
import uuid
33

4-
from pulpcore.client.pulp_python import ApiException, AsyncOperationResponse
54
from pulp_python.tests.functional.constants import (
65
PYTHON_EGG_FILENAME,
76
PYTHON_EGG_SHA256,
@@ -27,19 +26,28 @@ def _gen_users(role_names=list()):
2726

2827

2928
@pytest.fixture
30-
def try_action(monitor_task):
29+
def try_action(python_bindings, monitor_task):
3130
def _try_action(user, client, action, outcome, *args, **kwargs):
3231
action_api = getattr(client, f"{action}_with_http_info")
3332
try:
3433
with user:
35-
response, status, _ = action_api(*args, **kwargs, _return_http_data_only=False)
36-
if isinstance(response, AsyncOperationResponse):
37-
response = monitor_task(response.task)
38-
except ApiException as e:
34+
response = action_api(*args, **kwargs)
35+
if isinstance(response, tuple):
36+
# old bindings
37+
data, status_code, _ = response
38+
else:
39+
# new bindings
40+
data = response.data
41+
status_code = response.status_code
42+
if isinstance(data, python_bindings.module.AsyncOperationResponse):
43+
data = monitor_task(data.task)
44+
except python_bindings.module.ApiException as e:
3945
assert e.status == outcome, f"{e}"
4046
else:
41-
assert status == outcome, f"User performed {action} when they shouldn't been able to"
42-
return response
47+
assert (
48+
status_code == outcome
49+
), f"User performed {action} when they shouldn't been able to"
50+
return data
4351

4452
return _try_action
4553

0 commit comments

Comments
 (0)