From a4d4404be08283279678558ed5c0b06f7c601ad3 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Thu, 28 Jul 2022 09:58:05 +0200 Subject: [PATCH 1/5] add some tests on indexing with package --- quetz/tests/api/__init__.py | 0 quetz/tests/test_indexing.py | 107 +++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 quetz/tests/api/__init__.py diff --git a/quetz/tests/api/__init__.py b/quetz/tests/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/quetz/tests/test_indexing.py b/quetz/tests/test_indexing.py index 4393a241..dfdf4ed4 100644 --- a/quetz/tests/test_indexing.py +++ b/quetz/tests/test_indexing.py @@ -1,29 +1,66 @@ +import json +import os +from pathlib import Path import pytest from quetz.config import Config -from quetz.db_models import Channel +from quetz.dao import Dao +from quetz.db_models import Channel as Channel_model from quetz.tasks.indexing import update_indexes +from quetz.rest_models import Channel, Package +from quetz import channel_data + +from .api.conftest import * @pytest.fixture -def local_channel(db): +def empty_channeldata(dao): + return channel_data.export(dao, "") + + +def test_update_indexes_empty_channel( + config: Config, + public_channel, + dao, + empty_channeldata +): + pkgstore = config.get_package_store() + + update_indexes(dao, pkgstore, public_channel.name) + + files = pkgstore.list_files(public_channel.name) + + base_files = [ + 'channeldata.json', + 'index.html', + 'noarch/index.html', + 'noarch/repodata.json', + ] - channel = Channel(name="test-local-channel") - db.add(channel) - db.commit() + expected_files = base_files.copy() - yield channel + for suffix in ['.bz2', '.gz']: + expected_files.extend(s + suffix for s in base_files) - db.delete(channel) - db.commit() + assert sorted(files) == sorted(expected_files) + channel_dir = Path(pkgstore.channels_dir) / public_channel.name + with open(channel_dir / 'channeldata.json', 'r') as fd: + assert json.load(fd) == empty_channeldata -def test_update_indexes(config: Config, local_channel, dao): + +def test_update_indexes_empty_package( + config: Config, + public_channel, + public_package, + dao, + empty_channeldata +): pkgstore = config.get_package_store() - update_indexes(dao, pkgstore, local_channel.name) + update_indexes(dao, pkgstore, public_channel.name) - files = pkgstore.list_files(local_channel.name) + files = pkgstore.list_files(public_channel.name) base_files = [ 'channeldata.json', @@ -38,3 +75,51 @@ def test_update_indexes(config: Config, local_channel, dao): expected_files.extend(s + suffix for s in base_files) assert sorted(files) == sorted(expected_files) + + channel_dir = Path(pkgstore.channels_dir) / public_channel.name + with open(channel_dir / 'channeldata.json', 'r') as fd: + channeldata = json.load(fd) + + assert public_package.name in channeldata["packages"].keys() + + assert channeldata["packages"].pop(public_package.name) == {} + assert channeldata == empty_channeldata + + +def test_update_indexes_with_package_version( + config: Config, + public_channel, + public_package, + package_version, + dao +): + platform="linux-64" + pkgstore = config.get_package_store() + + update_indexes(dao, pkgstore, public_channel.name) + + files = pkgstore.list_files(public_channel.name) + + base_files = [ + 'channeldata.json', + 'index.html', + 'linux-64/index.html', + 'linux-64/repodata.json', + 'noarch/index.html', + 'noarch/repodata.json', + ] + + expected_files = base_files.copy() + + for suffix in ['.bz2', '.gz']: + expected_files.extend(s + suffix for s in base_files) + + expected_files.append(f"linux-64/{package_version.filename}") + + assert sorted(files) == sorted(expected_files) + + channel_dir = Path(pkgstore.channels_dir) / public_channel.name + with open(channel_dir / 'channeldata.json', 'r') as fd: + channeldata = json.load(fd) + + assert public_package.name in channeldata["packages"].keys() From df529ec58eec602b0de22760e924eae788336558 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Thu, 28 Jul 2022 16:05:27 +0200 Subject: [PATCH 2/5] Fix an API which was not updating the repodata on upload --- quetz/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quetz/main.py b/quetz/main.py index 631b24f9..b10ef506 100644 --- a/quetz/main.py +++ b/quetz/main.py @@ -1300,6 +1300,10 @@ def post_file_to_package( handle_package_files(package.channel, files, dao, auth, force, package=package) dao.update_channel_size(package.channel_name) + wrapped_bg_task = background_task_wrapper(indexing.update_indexes, logger) + # Background task to update indexes + background_tasks.add_task(wrapped_bg_task, dao, pkgstore, package.channel_name) + @api_router.post( "/channels/{channel_name}/upload/{filename}", status_code=201, tags=["upload"] From d7578deb50bb886f15fc3a819f74620bd5b1ee37 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Thu, 28 Jul 2022 17:07:43 +0200 Subject: [PATCH 3/5] Add tests on uploading a duplicate package version --- quetz/tests/api/test_main_packages.py | 70 ++++++++++++++++++ .../data/test-package-0.1-0_copy.tar.bz2 | Bin 0 -> 2725 bytes 2 files changed, 70 insertions(+) create mode 100644 quetz/tests/data/test-package-0.1-0_copy.tar.bz2 diff --git a/quetz/tests/api/test_main_packages.py b/quetz/tests/api/test_main_packages.py index 45f37a97..b7c262bb 100644 --- a/quetz/tests/api/test_main_packages.py +++ b/quetz/tests/api/test_main_packages.py @@ -1,4 +1,6 @@ +import json import os +import time from pathlib import Path from typing import BinaryIO @@ -326,6 +328,74 @@ def test_upload_package_version_wrong_filename( assert not os.path.exists(package_dir) +@pytest.mark.parametrize("package_name", ["test-package"]) +def test_upload_duplicate_package_version( + auth_client, + public_channel, + public_package, + package_name, + db, + config, + remove_package_versions, +): + pkgstore = config.get_package_store() + + package_filename = "test-package-0.1-0.tar.bz2" + package_filename_copy = "test-package-0.1-0_copy.tar.bz2" + + with open(package_filename, "rb") as fid: + files = {"files": (package_filename, fid)} + response = auth_client.post( + f"/api/channels/{public_channel.name}/packages/" + f"{public_package.name}/files/", + files=files, + ) + + package_dir = Path(pkgstore.channels_dir) / public_channel.name / 'linux-64' + with open(package_dir / 'repodata.json', 'r') as fd: + repodata_init = json.load(fd) + + with open(package_filename, "rb") as fid: + files = {"files": (package_filename, fid)} + response = auth_client.post( + f"/api/channels/{public_channel.name}/packages/" + f"{public_package.name}/files/", + files=files, + ) + assert response.status_code == 409 + detail = response.json()['detail'] + assert "Duplicate" in detail + + # Change the archive to test force update + os.remove(package_filename) + os.rename(package_filename_copy, package_filename) + + # Ensure the 'time_modified' value change in repodata.json + time.sleep(1) + + with open(package_filename, "rb") as fid: + files = {"files": (package_filename, fid)} + response = auth_client.post( + f"/api/channels/{public_channel.name}/packages/" + f"{public_package.name}/files/", + files=files, + data={"force": True}, + ) + + assert response.status_code == 201 + + with open(package_dir / 'repodata.json', 'r') as fd: + repodata = json.load(fd) + + assert repodata_init["info"] == repodata["info"] + assert repodata_init["packages"].keys() == repodata["packages"].keys() + repodata_init_pkg = repodata_init["packages"][package_filename] + repodata_pkg = repodata["packages"][package_filename] + assert repodata_init_pkg["time_modified"] != repodata_pkg["time_modified"] + assert repodata_init_pkg["md5"] != repodata_pkg["md5"] + assert repodata_init_pkg["sha256"] != repodata_pkg["sha256"] + + @pytest.mark.parametrize("package_name", ["test-package"]) def test_check_channel_size_limits( auth_client, public_channel, public_package, db, config diff --git a/quetz/tests/data/test-package-0.1-0_copy.tar.bz2 b/quetz/tests/data/test-package-0.1-0_copy.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..52b7318fb20ef3c953e7b03e4c27e8bcc30e60b6 GIT binary patch literal 2725 zcmV;W3R?9-T4**gL0KkKSvrL^Pyh?9f0N&kA|P0Y|MwqktxEs@|M~;~0RR9700>|U zylyepnl$mm^Aac2yl?bd$LA>s^El@cP5?OovYZ&1OwLr0uBU{q>KrH zBy{S})%xMd?qq_VhC)GLA4U&*$NrWM_XYIjh@^@E$VzcSo+|M*V?Ka-`ftR~@B6uq*_59g-#dsg~i6K)ms30cQY zsJ5-WJv8XT7}V)&Tx)%r-DCHDo0b@T#NjA=FL!YOk;kX5ndg9>&3Xiz)0N%(o&q^GWwa!@(9e>@}Hqys_{94Um(>?MM8Oi)BIMHCtvT8tdEO>Z8${NouE-@%+&7VHUjwhl>%=0pJylnDiqh$x6f6ch!3kp&_kvJpryU@R6- zsQ;cLZugF`lYf#DYfvG4?k#~c~Ut^CvLC!?z8-Uj>f z5bx2o5!M~@WkihGqR8l^;twGfn0N%aPN1wQF@rMF5WGp3Eo?d%A{eK`JEeDurmGW4 zSOiH1>W$uo?>JbTUKk-536NueYAj}D<)P}>vbcdlTGuW@N{SA_&{&3*6J!`&Fo7@lm_UTl5em5hFr|#Dm1rE=4hNJAxZfVq&bv;eQNXmQ8b}Ty!$gv+mxv)%I>J>^ z*Gnn^W6kwy33G#52#sc`jLvG*TMgH}a(LAm@BE z9K7ek0pX$4Q328D2OL1!GH&gNaSUmV9&rarkq-L1ReFMV;LI#0go4O`RZzG^8pJ~UJn=o}QUdbLUe_ST*q|W?e^b($ui=>V zS+b1GW;w7h=~Nb#=qr7J6~=q6rrp!XrV*Ph4;ci9jzG{CA4c6fgAmr^X#j%^^=Tz0 zYFhOm*beR5L~6waL>v9Rv^11K`M!g>CGq&(<8)z4$(~fJYDr=`gv=)eaH()I18%=0 z6L&rVBz~wP)DMrlZH2_yhE9 zkCr#(h?ptKqvB(`o#StMB^(%FJOz{>JO)3OG<@`C2!|>~1R4-bQ}bq55;=jPVW(jN z1Xa4T$J92Ou>fv9nt=jErcY5eC|RA^ zg=V>ss%f6vNV|U34L%JTAdj3s;%CbR+z$vBG-civb*RQV3}9_UD2Lb8b#9VS-JwGe zw=W%Y5MMV5J}pmIeBCFR7L5&RyEF?kv)gk2s3#Hj=Ca%AwlT`k$s=R~aQ~vnWBfPhNIi z6SaU?z`_7P5eTt{WDPiYe*8<}!pkr|YP*_#4Az?Q-IjtEkU~WxB|fCYwAZ*1JP-h& z$TqR&lLHr#9xXvuv7qwqbL<5}QeiJ}GqPbJlR0kG5%&GxKi~KN&-=yD>PceX(OspW zRlWqOlU7BD;r#0-mlu2K)AHEM4$k&$@of+KP@);Y~Ptt+Dqyn|?IqKnAteRaX_ zWZk*1K3G^f8p~|efH`$4HN?qIt){e=9(&ya#>=m@2{e9~SEqh4O;D}0fU(OGb48x9 zh=vviVo>A|X$uWmR?~%faEP;!0hGu>$aEQQ$f0Uqe#Q1$pqi`%_2+TImJA_t%6DD3}D?R^eR(s#zvYw=gwwUjrTMA_k>ubZw%O7?wBeA(Wgzz9xlfV-tW= z63pmSrJ*Jl0bpz=6hgJG-c!2j8UTqfNW73hfrE3j64EBia5FQWf-sQn7xls?gTX$i z$-dB@h9ZcF;=?-dEg9OxXCUMK;vox0qHh?47C<0E<|Wfbe1%eihJ;28j(|5+BnF}- zch;^Kd)p2w5u&JRbWDSC8p&b;n6;R|z)m|#2d{MHe=wSa1z{~9ER|ppv~j~bOj>x$n2QqEP1ZP6-#z>)cwDt{)ha%{#nOd-g&74(x(#OnTl=8FiYDYh zhuOCh#G=};txI5G#UcnPK0x4RCAGC%TV_H{fa^6D(y5RsR2qswz*WORg$bFkNRZwN z(Oh)C%$nAAzQwtL;33cfSC4KrD^QS7N3Vxr;9%=D{{l2H&L Date: Thu, 28 Jul 2022 18:20:17 +0200 Subject: [PATCH 4/5] Groups duplicate fixtures --- quetz/tests/api/conftest.py | 111 ++----------------------------- quetz/tests/conftest.py | 109 +++++++++++++++++++++++++++++- quetz/tests/test_dao.py | 10 --- quetz/tests/test_indexing.py | 30 ++------- quetz/tests/test_jobs.py | 20 ------ quetz/tests/test_tasks.py | 5 -- quetz/tests/test_versionorder.py | 10 --- 7 files changed, 117 insertions(+), 178 deletions(-) diff --git a/quetz/tests/api/conftest.py b/quetz/tests/api/conftest.py index d7abe02a..8f9784aa 100644 --- a/quetz/tests/api/conftest.py +++ b/quetz/tests/api/conftest.py @@ -3,22 +3,10 @@ import pytest -from quetz.config import Config -from quetz.dao import Dao -from quetz.db_models import Identity, PackageVersion, Profile, User +from quetz.db_models import Identity, Profile, User from quetz.rest_models import Channel, Package -@pytest.fixture -def package_name(): - return "my-package" - - -@pytest.fixture -def channel_name(): - return "my-channel" - - @pytest.fixture def private_channel(dao, other_user): @@ -43,7 +31,9 @@ def private_package(dao, other_user, private_channel): @pytest.fixture -def private_package_version(dao, private_channel, private_package, other_user, config): +def private_package_version( + dao, private_channel, private_package, other_user, config, package_name +): package_format = "tarbz2" package_info = "{}" channel_name = private_channel.name @@ -77,68 +67,6 @@ def private_package_version(dao, private_channel, private_package, other_user, c return version -@pytest.fixture -def make_package_version( - db, - user, - public_channel, - channel_name, - package_name, - public_package, - dao: Dao, - config: Config, -): - - pkgstore = config.get_package_store() - - versions = [] - - def _make_package_version(filename, version_number, platform="linux-64"): - filename = Path(filename) - with open(filename, "rb") as fid: - pkgstore.add_file(fid.read(), channel_name, platform / filename) - package_format = "tarbz2" - package_info = "{}" - version = dao.create_version( - channel_name, - package_name, - package_format, - platform, - version_number, - 0, - "", - str(filename), - package_info, - user.id, - size=11, - ) - - dao.update_package_channeldata( - channel_name, - package_name, - {'name': package_name, 'subdirs': [platform]}, - ) - - dao.update_channel_size(channel_name) - - versions.append(version) - - return version - - yield _make_package_version - - for version in versions: - db.query(PackageVersion).filter(PackageVersion.id == version.id).delete() - db.commit() - - -@pytest.fixture -def package_version(db, make_package_version): - version = make_package_version("test-package-0.1-0.tar.bz2", "0.1") - - return version - - @pytest.fixture() def other_user_without_profile(db): user = User(id=uuid.uuid4().bytes, username="other") @@ -163,37 +91,6 @@ def other_user(other_user_without_profile, db): yield other_user_without_profile -@pytest.fixture -def channel_role(): - return "owner" - - -@pytest.fixture -def package_role(): - return "owner" - - -@pytest.fixture -def public_channel(dao: Dao, user, channel_role, channel_name): - - channel_data = Channel(name=channel_name, private=False) - channel = dao.create_channel(channel_data, user.id, channel_role) - - return channel - - -@pytest.fixture -def public_package(db, user, public_channel, dao, package_role, package_name): - - package_data = Package(name=package_name) - - package = dao.create_package( - public_channel.name, package_data, user.id, package_role - ) - - return package - - @pytest.fixture def pkgstore(config): return config.get_package_store() diff --git a/quetz/tests/conftest.py b/quetz/tests/conftest.py index d7e15bf5..3047c9eb 100644 --- a/quetz/tests/conftest.py +++ b/quetz/tests/conftest.py @@ -10,10 +10,14 @@ import uuid +from pathlib import Path from pytest import fixture -from quetz.db_models import Profile, User +from quetz.config import Config +from quetz.dao import Dao +from quetz.db_models import PackageVersion, Profile, User +from quetz.rest_models import Channel, Package pytest_plugins = "quetz.testing.fixtures" @@ -53,3 +57,106 @@ def user(db, user_without_profile): ).delete() db.commit() + + +@fixture +def make_package_version( + db, + user, + public_channel, + channel_name, + package_name, + public_package, + dao: Dao, + config: Config, +): + + pkgstore = config.get_package_store() + + versions = [] + + def _make_package_version(filename, version_number, platform="linux-64"): + filename = Path(filename) + with open(filename, "rb") as fid: + pkgstore.add_file(fid.read(), channel_name, platform / filename) + package_format = "tarbz2" + package_info = "{}" + version = dao.create_version( + channel_name, + package_name, + package_format, + platform, + version_number, + 0, + "", + str(filename), + package_info, + user.id, + size=11, + ) + + dao.update_package_channeldata( + channel_name, + package_name, + {'name': package_name, 'subdirs': [platform]}, + ) + + dao.update_channel_size(channel_name) + + versions.append(version) + + return version + + yield _make_package_version + + for version in versions: + db.query(PackageVersion).filter(PackageVersion.id == version.id).delete() + db.commit() + + +@fixture +def package_version(db, make_package_version): + version = make_package_version("test-package-0.1-0.tar.bz2", "0.1") + + return version + + +@fixture +def public_channel(dao: Dao, user, channel_role, channel_name): + + channel_data = Channel(name=channel_name, private=False) + channel = dao.create_channel(channel_data, user.id, channel_role) + + return channel + + +@fixture +def public_package(db, user, public_channel, dao, package_role, package_name): + + package_data = Package(name=package_name) + + package = dao.create_package( + public_channel.name, package_data, user.id, package_role + ) + + return package + + +@fixture +def channel_name(): + return "my-channel" + + +@fixture +def package_name(): + return "my-package" + + +@fixture +def channel_role(): + return "owner" + + +@fixture +def package_role(): + return "owner" diff --git a/quetz/tests/test_dao.py b/quetz/tests/test_dao.py index 180a0699..bd95106d 100644 --- a/quetz/tests/test_dao.py +++ b/quetz/tests/test_dao.py @@ -12,16 +12,6 @@ from quetz.metrics.db_models import IntervalType, PackageVersionMetric, round_timestamp -@pytest.fixture -def package_name(): - return "my-package" - - -@pytest.fixture -def channel_name(): - return "my-channel" - - @pytest.fixture def channel(dao, db, user, channel_name): diff --git a/quetz/tests/test_indexing.py b/quetz/tests/test_indexing.py index dfdf4ed4..dce32551 100644 --- a/quetz/tests/test_indexing.py +++ b/quetz/tests/test_indexing.py @@ -1,16 +1,10 @@ import json -import os from pathlib import Path + import pytest -from quetz.config import Config -from quetz.dao import Dao -from quetz.db_models import Channel as Channel_model -from quetz.tasks.indexing import update_indexes -from quetz.rest_models import Channel, Package from quetz import channel_data - -from .api.conftest import * +from quetz.tasks.indexing import update_indexes @pytest.fixture @@ -18,12 +12,7 @@ def empty_channeldata(dao): return channel_data.export(dao, "") -def test_update_indexes_empty_channel( - config: Config, - public_channel, - dao, - empty_channeldata -): +def test_update_indexes_empty_channel(config, public_channel, dao, empty_channeldata): pkgstore = config.get_package_store() update_indexes(dao, pkgstore, public_channel.name) @@ -50,11 +39,7 @@ def test_update_indexes_empty_channel( def test_update_indexes_empty_package( - config: Config, - public_channel, - public_package, - dao, - empty_channeldata + config, public_channel, public_package, dao, empty_channeldata ): pkgstore = config.get_package_store() @@ -87,13 +72,8 @@ def test_update_indexes_empty_package( def test_update_indexes_with_package_version( - config: Config, - public_channel, - public_package, - package_version, - dao + config, public_channel, public_package, package_version, dao ): - platform="linux-64" pkgstore = config.get_package_store() update_indexes(dao, pkgstore, public_channel.name) diff --git a/quetz/tests/test_jobs.py b/quetz/tests/test_jobs.py index 6c7d7124..6873781b 100644 --- a/quetz/tests/test_jobs.py +++ b/quetz/tests/test_jobs.py @@ -31,16 +31,6 @@ def sqlite_in_memory(): return False -@pytest.fixture -def package_name(): - return "my-package" - - -@pytest.fixture -def channel_name(): - return "my-channel" - - def add_package_version( filename, package_version, channel_name, user, dao, package_name=None ): @@ -98,16 +88,6 @@ def package_version( db.commit() -@pytest.fixture -def channel_role(): - return "owner" - - -@pytest.fixture -def package_role(): - return "owner" - - @pytest.fixture def public_channel(dao: Dao, user, channel_role, channel_name, db): diff --git a/quetz/tests/test_tasks.py b/quetz/tests/test_tasks.py index 102fc118..93c36b4e 100644 --- a/quetz/tests/test_tasks.py +++ b/quetz/tests/test_tasks.py @@ -9,11 +9,6 @@ from quetz.tasks.reindexing import reindex_packages_from_store -@pytest.fixture -def channel_name(): - return "my-channel" - - @pytest.fixture def pkgstore(config): pkgstore = config.get_package_store() diff --git a/quetz/tests/test_versionorder.py b/quetz/tests/test_versionorder.py index 961d11db..cf82a690 100644 --- a/quetz/tests/test_versionorder.py +++ b/quetz/tests/test_versionorder.py @@ -19,16 +19,6 @@ from quetz.versionorder import VersionOrder -@pytest.fixture -def package_name(): - return "my-package" - - -@pytest.fixture -def channel_name(): - return "my-channel" - - def test_versionorder(): versions = [ ("0.4", [[0], [0], [4]]), From 6a4117666302150c1bbae4a8c9b02f2733b65a49 Mon Sep 17 00:00:00 2001 From: Nicolas Brichet Date: Thu, 28 Jul 2022 23:20:02 +0200 Subject: [PATCH 5/5] (1) Builds repodata after deleting a package version, and (2) add tests on repodata after deleting a package --- quetz/main.py | 5 +++ quetz/tests/api/test_main_packages.py | 47 +++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/quetz/main.py b/quetz/main.py index b10ef506..3a076f3f 100644 --- a/quetz/main.py +++ b/quetz/main.py @@ -1090,6 +1090,7 @@ def delete_package_version( filename: str, channel_name: str, package_name: str, + background_tasks: BackgroundTasks, dao: Dao = Depends(get_dao), db=Depends(get_db), auth: authorization.Rules = Depends(get_rules), @@ -1115,6 +1116,10 @@ def delete_package_version( dao.update_channel_size(channel_name) + wrapped_bg_task = background_task_wrapper(indexing.update_indexes, logger) + # Background task to update indexes + background_tasks.add_task(wrapped_bg_task, dao, pkgstore, channel_name, [platform]) + @api_router.get( "/packages/search/", response_model=List[rest_models.PackageSearch], tags=["search"] diff --git a/quetz/tests/api/test_main_packages.py b/quetz/tests/api/test_main_packages.py index b7c262bb..5c2f47d1 100644 --- a/quetz/tests/api/test_main_packages.py +++ b/quetz/tests/api/test_main_packages.py @@ -12,7 +12,6 @@ from quetz.config import Config from quetz.db_models import ChannelMember, Package, PackageMember, PackageVersion from quetz.errors import ValidationError -from quetz.pkgstores import PackageStore from quetz.tasks.indexing import update_indexes @@ -74,10 +73,22 @@ def test_delete_package_versions_with_package( update_indexes(dao, pkgstore, public_channel.name) + # Get package files package_filenames = [ os.path.join(version.platform, version.filename) for version in public_package.package_versions # type: ignore ] + + # Get repodata content + package_dir = Path(pkgstore.channels_dir) / public_channel.name / 'linux-64' + with open(package_dir / 'repodata.json', 'r') as fd: + repodata = json.load(fd) + + # Check that all packages are initially in repodata + for filename in package_filenames: + assert os.path.basename(filename) in repodata["packages"].keys() + + # Get channel files init_files = sorted(pkgstore.list_files(public_channel.name)) response = auth_client.delete( @@ -97,9 +108,19 @@ def test_delete_package_versions_with_package( assert len(versions) == 0 + # Check that repodata content has been updated + with open(package_dir / 'repodata.json', 'r') as fd: + repodata = json.load(fd) + + assert repodata["info"] == repodata["info"] + + # Remove package files from files list + # Check that packages have been removed from repodata for filename in package_filenames: init_files.remove(filename) + assert os.path.basename(filename) not in repodata["packages"] + # Check that the package tree files is the same except for package files files = sorted(pkgstore.list_files(public_channel.name)) assert files == init_files @@ -314,10 +335,6 @@ def test_upload_package_version_wrong_filename( files=files, ) - with open(package_filename, "rb") as fid: - condainfo = CondaInfo(fid, package_filename) - condainfo._parse_conda() - package_dir = Path(pkgstore.channels_dir) / public_channel.name / 'linux-64' assert response.status_code == 400 @@ -351,10 +368,12 @@ def test_upload_duplicate_package_version( files=files, ) + # Get repodata content package_dir = Path(pkgstore.channels_dir) / public_channel.name / 'linux-64' with open(package_dir / 'repodata.json', 'r') as fd: repodata_init = json.load(fd) + # Try submitting the same package without 'force' flag with open(package_filename, "rb") as fid: files = {"files": (package_filename, fid)} response = auth_client.post( @@ -373,6 +392,7 @@ def test_upload_duplicate_package_version( # Ensure the 'time_modified' value change in repodata.json time.sleep(1) + # Submit the same package with 'force' flag with open(package_filename, "rb") as fid: files = {"files": (package_filename, fid)} response = auth_client.post( @@ -384,6 +404,7 @@ def test_upload_duplicate_package_version( assert response.status_code == 201 + # Check that repodata content has been updated with open(package_dir / 'repodata.json', 'r') as fd: repodata = json.load(fd) @@ -423,13 +444,22 @@ def test_check_channel_size_limits( def test_delete_package_version( - auth_client, public_channel, package_version, dao, pkgstore: PackageStore, db + auth_client, public_channel, package_version, dao, pkgstore, db ): assert public_channel.size > 0 assert public_channel.size == package_version.size filename = "test-package-0.1-0.tar.bz2" platform = "linux-64" + + update_indexes(dao, pkgstore, public_channel.name) + + # Get repodata content and check that package is inside + package_dir = Path(pkgstore.channels_dir) / public_channel.name / 'linux-64' + with open(package_dir / 'repodata.json', 'r') as fd: + repodata = json.load(fd) + assert filename in repodata["packages"].keys() + response = auth_client.delete( f"/api/channels/{public_channel.name}/" f"packages/{package_version.package_name}/versions/{platform}/{filename}" @@ -451,6 +481,11 @@ def test_delete_package_version( db.refresh(public_channel) assert public_channel.size == 0 + # Check that repodata content has been updated + with open(package_dir / 'repodata.json', 'r') as fd: + repodata = json.load(fd) + assert filename not in repodata["packages"].keys() + def test_package_name_length_limit(auth_client, public_channel, db):