Changeset View
Standalone View
swh/loader/pypi/tests/test_loader.py
# Copyright (C) 2016-2018 The Software Heritage developers | # Copyright (C) 2016-2018 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import json | import json | ||||
import tempfile | import tempfile | ||||
import pytest | import pytest | ||||
from swh.loader.core.tests import BaseLoaderTest, LoaderNoStorage | from swh.loader.core.tests import BaseLoaderTest | ||||
from swh.loader.pypi.client import PyPIProject | from swh.loader.pypi.client import PyPIProject | ||||
from swh.loader.pypi.loader import PyPILoader | from swh.loader.pypi.loader import PyPILoader | ||||
from swh.model import hashutil | from swh.model import hashutil | ||||
from .common import RESOURCES_PATH, PyPIClientWithCache | from .common import RESOURCES_PATH, PyPIClientWithCache | ||||
class TestPyPILoader(LoaderNoStorage, PyPILoader): | _LOADER_TESTS_CONFIG = { | ||||
'cache': False, | |||||
'cache_dir': '', | |||||
'content_packet_size': 10000, | |||||
'content_packet_size_bytes': 104857600, | |||||
'content_size_limit': 104857600, | |||||
'debug': False, | |||||
'directory_packet_size': 25000, | |||||
'log_db': 'dbname=softwareheritage-log', | |||||
'occurrence_packet_size': 100000, | |||||
'release_packet_size': 100000, | |||||
'revision_packet_size': 100000, | |||||
'save_data': False, | |||||
'save_data_path': '', | |||||
'send_contents': True, | |||||
'send_directories': True, | |||||
'send_releases': True, | |||||
'send_revisions': True, | |||||
'send_snapshot': True, | |||||
'storage': {'args': {}, 'cls': 'memory'}, | |||||
'temp_directory': '/tmp/swh.loader.pypi/' | |||||
} | |||||
class PyPILoaderTest(PyPILoader): | |||||
"""Real PyPILoader for test purposes (storage and pypi interactions | """Real PyPILoader for test purposes (storage and pypi interactions | ||||
inhibited) | inhibited) | ||||
""" | """ | ||||
def __init__(self, project_name, json_filename=None): | def __init__(self, project_name, json_filename=None): | ||||
if not json_filename: # defaulting to using same name as project | if not json_filename: # defaulting to using same name as project | ||||
json_filename = '%s.json' % project_name | json_filename = '%s.json' % project_name | ||||
project_metadata_file = '%s/%s' % (RESOURCES_PATH, json_filename) | project_metadata_file = '%s/%s' % (RESOURCES_PATH, json_filename) | ||||
project_metadata_url = 'https://pypi.org/pypi/%s/json' % project_name | project_metadata_url = 'https://pypi.org/pypi/%s/json' % project_name | ||||
with open(project_metadata_file) as f: | with open(project_metadata_file) as f: | ||||
data = json.load(f) | data = json.load(f) | ||||
self.temp_dir = tempfile.mkdtemp( | self.temp_dir = tempfile.mkdtemp( | ||||
dir='/tmp/', prefix='swh.loader.pypi.tests-') | dir='/tmp/', prefix='swh.loader.pypi.tests-') | ||||
# Will use the pypi with cache | # Will use the pypi with cache | ||||
client = PyPIClientWithCache( | client = PyPIClientWithCache( | ||||
temp_directory=self.temp_dir, cache_dir=RESOURCES_PATH) | temp_directory=self.temp_dir, cache_dir=RESOURCES_PATH) | ||||
super().__init__(client=client) | super().__init__(client=client) | ||||
vlorentz: also override it (see D684) | |||||
self.project = PyPIProject( | self.project = PyPIProject( | ||||
client=client, | client=client, | ||||
project=project_name, | project=project_name, | ||||
project_metadata_url=project_metadata_url, | project_metadata_url=project_metadata_url, | ||||
data=data) | data=data) | ||||
def parse_config_file(self, *args, **kwargs): | |||||
Not Done Inline ActionsIf you do this, you actually read the configuration from disk (so that can actually diverge from dev box if there is some locally). ardumont: If you do this, you actually read the configuration from disk (so that can actually diverge… | |||||
Done Inline ActionsIndeed you are right, we can have config loaded from files proceeding this way and welcome the side effects. What I am trying to achieve here is to load the default config without duplicating it in the tests code. I came with this other solution that loads it without reading config files on disk. from swh.core.config import ( merge_default_configs, read as config_read, SWH_DEFAULT_GLOBAL_CONFIG ) def parse_config_file(self, *args, **kwargs): default_conf = merge_default_configs(self.DEFAULT_CONFIG, self.ADDITIONAL_CONFIG, SWH_DEFAULT_GLOBAL_CONFIG) config = config_read(default_conf=default_conf) config['storage'] = {'cls': 'memory', 'args': {}} return config But apparently, the plan is to remove implicit configuration (T1410) and thus, based on my understanding, relies only on configuration files. So I am a little confused on what is the proper solution here. anlambert: Indeed you are right, we can have config loaded from files proceeding this way and welcome the… | |||||
Not Done Inline ActionsCopy the default config to some global/constant, and return it vlorentz: Copy the default config to some global/constant, and return it | |||||
Not Done Inline ActionsYes, for now, do as proposed by vlorentz.
What i mean was, keep your override implementation of parse_config_file but remove the call to super().parse_config_file. Something like D770#inline-4166 would do.
I think the plan will be to remove implicit configuration by explicitely passing configuration along where it's needed. So that may simplify this anyway but now we will know where to look for changes ;) ardumont: Yes, for now, do as proposed by vlorentz.
That will be only duplicated once in the tests and… | |||||
Done Inline ActionsAll right, I will do as proposed. But I still do not like that configuration duplication, this can be a source of problem For instance, for the pypi loader, the configuration is the following: { 'cache': False, 'cache_dir': '', 'content_packet_size': 10000, 'content_packet_size_bytes': 104857600, 'content_size_limit': 104857600, 'debug': False, 'directory_packet_size': 25000, 'log_db': 'dbname=softwareheritage-log', 'occurrence_packet_size': 100000, 'release_packet_size': 100000, 'revision_packet_size': 100000, 'save_data': False, 'save_data_path': '', 'send_contents': True, 'send_directories': True, 'send_releases': True, 'send_revisions': True, 'send_snapshot': True, 'storage': {'args': {}, 'cls': 'memory'}, 'temp_directory': '/tmp/swh.loader.pypi/' } That's quite a lot of configuration keys, with some coming from the swh-core module anlambert: All right, I will do as proposed.
But I still do not like that configuration duplication, this… | |||||
Not Done Inline ActionsI agree. It's far from perfect. I do not like it either. It's a momentary trade-off. I like it better than the current side-effect of loading from disk. Note that the config from swh-core has not being changed for a while now (it still could but it has not for a long time, at least 2 years IIRC ;). ardumont: I agree. It's far from perfect. I do not like it either. It's a momentary trade-off.
I like it… | |||||
return _LOADER_TESTS_CONFIG | |||||
def prepare(self, project_name, origin_url, | def prepare(self, project_name, origin_url, | ||||
origin_metadata_url=None): | origin_metadata_url=None): | ||||
self.project_name = project_name | self.project_name = project_name | ||||
self.origin_url = origin_url | self.origin_url = origin_url | ||||
self.origin_metadata_url = origin_metadata_url | self.origin_metadata_url = origin_metadata_url | ||||
self.visit = 1 # first visit | self.visit = 1 # first visit | ||||
self._prepare_state() | self._prepare_state() | ||||
Show All 11 Lines | def setUp(self, project_name='0805nexter', | ||||
self.tmp_root_path = tempfile.mkdtemp( | self.tmp_root_path = tempfile.mkdtemp( | ||||
dir='/tmp', prefix='swh.loader.pypi.tests-') | dir='/tmp', prefix='swh.loader.pypi.tests-') | ||||
self._project = project_name | self._project = project_name | ||||
self._origin_url = '%s/pypi/%s/' % (dummy_pypi_instance, project_name) | self._origin_url = '%s/pypi/%s/' % (dummy_pypi_instance, project_name) | ||||
self._project_metadata_url = '%s/pypi/%s/json' % ( | self._project_metadata_url = '%s/pypi/%s/json' % ( | ||||
dummy_pypi_instance, project_name) | dummy_pypi_instance, project_name) | ||||
class PyPILoaderNoSnapshot(TestPyPILoader): | class PyPILoaderNoSnapshot(PyPILoaderTest): | ||||
"""Same as TestPyPILoader with no prior snapshot seen | """Same as PyPILoaderTest with no prior snapshot seen | ||||
""" | """ | ||||
def _last_snapshot(self): | def _last_snapshot(self): | ||||
return None | return None | ||||
class LoaderITest(PyPIBaseLoaderTest): | class LoaderITest(PyPIBaseLoaderTest): | ||||
def setUp(self, project_name='0805nexter', | def setUp(self, project_name='0805nexter', | ||||
dummy_pypi_instance='https://dummy.org'): | dummy_pypi_instance='https://dummy.org'): | ||||
super().setUp(project_name, dummy_pypi_instance) | super().setUp(project_name, dummy_pypi_instance) | ||||
self.loader = PyPILoaderNoSnapshot(project_name=project_name) | self.loader = PyPILoaderNoSnapshot(project_name=project_name) | ||||
self.storage = self.loader.storage | |||||
def test_load(self): | def test_load(self): | ||||
"""Load a pypi origin | """Load a pypi origin | ||||
""" | """ | ||||
# when | # when | ||||
self.loader.load( | self.loader.load( | ||||
self._project, self._origin_url, self._project_metadata_url) | self._project, self._origin_url, self._project_metadata_url) | ||||
Show All 11 Lines | def test_load(self): | ||||
'a61e24cdfdab3bb7817f6be85d37a3e666b34566', | 'a61e24cdfdab3bb7817f6be85d37a3e666b34566', | ||||
'938c33483285fd8ad57f15497f538320df82aeb8', | '938c33483285fd8ad57f15497f538320df82aeb8', | ||||
'a27576d60e08c94a05006d2e6d540c0fdb5f38c8', | 'a27576d60e08c94a05006d2e6d540c0fdb5f38c8', | ||||
'405859113963cb7a797642b45f171d6360425d16', | '405859113963cb7a797642b45f171d6360425d16', | ||||
'e5686aa568fdb1d19d7f1329267082fe40482d31', | 'e5686aa568fdb1d19d7f1329267082fe40482d31', | ||||
'83ecf6ec1114fd260ca7a833a2d165e71258c338', | '83ecf6ec1114fd260ca7a833a2d165e71258c338', | ||||
] | ] | ||||
self.assertContentsOk(expected_contents) | self.assertContentsContain(expected_contents) | ||||
expected_directories = [ | expected_directories = [ | ||||
'05219ba38bc542d4345d5638af1ed56c7d43ca7d', | '05219ba38bc542d4345d5638af1ed56c7d43ca7d', | ||||
'cf019eb456cf6f78d8c4674596f1c9a97ece8f44', | 'cf019eb456cf6f78d8c4674596f1c9a97ece8f44', | ||||
'b178b66bd22383d5f16f4f5c923d39ca798861b4', | 'b178b66bd22383d5f16f4f5c923d39ca798861b4', | ||||
'c3a58f8b57433a4b56caaa5033ae2e0931405338', | 'c3a58f8b57433a4b56caaa5033ae2e0931405338', | ||||
] | ] | ||||
self.assertDirectoriesOk(expected_directories) | self.assertDirectoriesContain(expected_directories) | ||||
# {revision hash: directory hash} | # {revision hash: directory hash} | ||||
expected_revisions = { | expected_revisions = { | ||||
'4c99891f93b81450385777235a37b5e966dd1571': '05219ba38bc542d4345d5638af1ed56c7d43ca7d', # noqa | '4c99891f93b81450385777235a37b5e966dd1571': '05219ba38bc542d4345d5638af1ed56c7d43ca7d', # noqa | ||||
'e445da4da22b31bfebb6ffc4383dbf839a074d21': 'b178b66bd22383d5f16f4f5c923d39ca798861b4', # noqa | 'e445da4da22b31bfebb6ffc4383dbf839a074d21': 'b178b66bd22383d5f16f4f5c923d39ca798861b4', # noqa | ||||
} | } | ||||
self.assertRevisionsOk(expected_revisions) | self.assertRevisionsContain(expected_revisions) | ||||
expected_branches = { | expected_branches = { | ||||
'releases/1.1.0': { | 'releases/1.1.0': { | ||||
'target': '4c99891f93b81450385777235a37b5e966dd1571', | 'target': '4c99891f93b81450385777235a37b5e966dd1571', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'releases/1.2.0': { | 'releases/1.2.0': { | ||||
'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | 'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'HEAD': { | 'HEAD': { | ||||
'target': 'releases/1.2.0', | 'target': 'releases/1.2.0', | ||||
'target_type': 'alias', | 'target_type': 'alias', | ||||
}, | }, | ||||
} | } | ||||
self.assertSnapshotOk('ba6e158ada75d0b3cfb209ffdf6daa4ed34a227a', | self.assertSnapshotEqual('ba6e158ada75d0b3cfb209ffdf6daa4ed34a227a', | ||||
expected_branches) | expected_branches) | ||||
self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | ||||
self.assertEqual(self.loader.visit_status(), 'full') | self.assertEqual(self.loader.visit_status(), 'full') | ||||
class PyPILoaderWithSnapshot(TestPyPILoader): | class PyPILoaderWithSnapshot(PyPILoaderTest): | ||||
"""This loader provides a snapshot and lists corresponding seen | """This loader provides a snapshot and lists corresponding seen | ||||
release artifacts. | release artifacts. | ||||
""" | """ | ||||
def _last_snapshot(self): | def _last_snapshot(self): | ||||
"""Return last visited snapshot""" | """Return last visited snapshot""" | ||||
return { | return { | ||||
'id': b'\xban\x15\x8a\xdau\xd0\xb3\xcf\xb2\t\xff\xdfm\xaaN\xd3J"z', # noqa | 'id': b'\xban\x15\x8a\xdau\xd0\xb3\xcf\xb2\t\xff\xdfm\xaaN\xd3J"z', # noqa | ||||
Show All 36 Lines | class LoaderNoNewChangesSinceLastVisitITest(PyPIBaseLoaderTest): | ||||
If nothing changes in between visits, the snapshot for the visit | If nothing changes in between visits, the snapshot for the visit | ||||
must stay the same as the first visit. | must stay the same as the first visit. | ||||
""" | """ | ||||
def setUp(self, project_name='0805nexter', | def setUp(self, project_name='0805nexter', | ||||
dummy_pypi_instance='https://dummy.org'): | dummy_pypi_instance='https://dummy.org'): | ||||
super().setUp(project_name, dummy_pypi_instance) | super().setUp(project_name, dummy_pypi_instance) | ||||
self.loader = PyPILoaderWithSnapshot(project_name=project_name) | self.loader = PyPILoaderWithSnapshot(project_name=project_name) | ||||
self.storage = self.loader.storage | |||||
def test_load(self): | def test_load(self): | ||||
"""Load a PyPI origin without new changes results in 1 same snapshot | """Load a PyPI origin without new changes results in 1 same snapshot | ||||
""" | """ | ||||
# when | # when | ||||
self.loader.load( | self.loader.load( | ||||
self._project, self._origin_url, self._project_metadata_url) | self._project, self._origin_url, self._project_metadata_url) | ||||
# then | # then | ||||
self.assertCountContents(0) | self.assertCountContents(0) | ||||
self.assertCountDirectories(0) | self.assertCountDirectories(0) | ||||
self.assertCountRevisions(0) | self.assertCountRevisions(0) | ||||
self.assertCountReleases(0) | self.assertCountReleases(0) | ||||
self.assertCountSnapshots(1) | self.assertCountSnapshots(1) | ||||
self.assertContentsOk([]) | self.assertContentsContain([]) | ||||
self.assertDirectoriesOk([]) | self.assertDirectoriesContain([]) | ||||
self.assertRevisionsOk(expected_revisions={}) | self.assertRevisionsContain(expected_revisions={}) | ||||
expected_snapshot_id = 'ba6e158ada75d0b3cfb209ffdf6daa4ed34a227a' | expected_snapshot_id = 'ba6e158ada75d0b3cfb209ffdf6daa4ed34a227a' | ||||
expected_branches = { | expected_branches = { | ||||
'releases/1.1.0': { | 'releases/1.1.0': { | ||||
'target': '4c99891f93b81450385777235a37b5e966dd1571', | 'target': '4c99891f93b81450385777235a37b5e966dd1571', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'releases/1.2.0': { | 'releases/1.2.0': { | ||||
'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | 'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'HEAD': { | 'HEAD': { | ||||
'target': 'releases/1.2.0', | 'target': 'releases/1.2.0', | ||||
'target_type': 'alias', | 'target_type': 'alias', | ||||
}, | }, | ||||
} | } | ||||
self.assertSnapshotOk(expected_snapshot_id, expected_branches) | self.assertSnapshotEqual(expected_snapshot_id, expected_branches) | ||||
_id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | _id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | ||||
self.assertEqual(expected_snapshot_id, _id) | self.assertEqual(expected_snapshot_id, _id) | ||||
self.assertEqual(self.loader.load_status(), {'status': 'uneventful'}) | self.assertEqual(self.loader.load_status(), {'status': 'uneventful'}) | ||||
self.assertEqual(self.loader.visit_status(), 'full') | self.assertEqual(self.loader.visit_status(), 'full') | ||||
Show All 12 Lines | class LoaderNewChangesSinceLastVisitITest(PyPIBaseLoaderTest): | ||||
""" | """ | ||||
def setUp(self, project_name='0805nexter', | def setUp(self, project_name='0805nexter', | ||||
dummy_pypi_instance='https://dummy.org'): | dummy_pypi_instance='https://dummy.org'): | ||||
super().setUp(project_name, dummy_pypi_instance) | super().setUp(project_name, dummy_pypi_instance) | ||||
self.loader = PyPILoaderWithSnapshot( | self.loader = PyPILoaderWithSnapshot( | ||||
project_name=project_name, | project_name=project_name, | ||||
json_filename='0805nexter+new-made-up-release.json') | json_filename='0805nexter+new-made-up-release.json') | ||||
self.storage = self.loader.storage | |||||
def test_load(self): | def test_load(self): | ||||
"""Load a PyPI origin with changes results in 1 new snapshot | """Load a PyPI origin with changes results in 1 new snapshot | ||||
""" | """ | ||||
# when | # when | ||||
self.loader.load( | self.loader.load( | ||||
self._project, self._origin_url, self._project_metadata_url) | self._project, self._origin_url, self._project_metadata_url) | ||||
Show All 10 Lines | def test_load(self): | ||||
expected_contents = [ | expected_contents = [ | ||||
'92689fa2b7fb4d4fc6fb195bf73a50c87c030639', # new one | '92689fa2b7fb4d4fc6fb195bf73a50c87c030639', # new one | ||||
'405859113963cb7a797642b45f171d6360425d16', | '405859113963cb7a797642b45f171d6360425d16', | ||||
'83ecf6ec1114fd260ca7a833a2d165e71258c338', | '83ecf6ec1114fd260ca7a833a2d165e71258c338', | ||||
'e5686aa568fdb1d19d7f1329267082fe40482d31', | 'e5686aa568fdb1d19d7f1329267082fe40482d31', | ||||
] | ] | ||||
self.assertContentsOk(expected_contents) | self.assertContentsContain(expected_contents) | ||||
expected_directories = [ | expected_directories = [ | ||||
'e226e7e4ad03b4fc1403d69a18ebdd6f2edd2b3a', | 'e226e7e4ad03b4fc1403d69a18ebdd6f2edd2b3a', | ||||
'52604d46843b898f5a43208045d09fcf8731631b', | '52604d46843b898f5a43208045d09fcf8731631b', | ||||
] | ] | ||||
self.assertDirectoriesOk(expected_directories) | self.assertDirectoriesContain(expected_directories) | ||||
expected_revisions = { | expected_revisions = { | ||||
'fb46e49605b0bbe69f8c53d315e89370e7c6cb5d': 'e226e7e4ad03b4fc1403d69a18ebdd6f2edd2b3a', # noqa | 'fb46e49605b0bbe69f8c53d315e89370e7c6cb5d': 'e226e7e4ad03b4fc1403d69a18ebdd6f2edd2b3a', # noqa | ||||
} | } | ||||
self.assertRevisionsOk(expected_revisions) | self.assertRevisionsContain(expected_revisions) | ||||
old_revisions = { | old_revisions = { | ||||
'4c99891f93b81450385777235a37b5e966dd1571': '05219ba38bc542d4345d5638af1ed56c7d43ca7d', # noqa | '4c99891f93b81450385777235a37b5e966dd1571': '05219ba38bc542d4345d5638af1ed56c7d43ca7d', # noqa | ||||
'e445da4da22b31bfebb6ffc4383dbf839a074d21': 'b178b66bd22383d5f16f4f5c923d39ca798861b4', # noqa | 'e445da4da22b31bfebb6ffc4383dbf839a074d21': 'b178b66bd22383d5f16f4f5c923d39ca798861b4', # noqa | ||||
} | } | ||||
for rev, dir_id in old_revisions.items(): | for rev, dir_id in old_revisions.items(): | ||||
expected_revisions[rev] = dir_id | expected_revisions[rev] = dir_id | ||||
Show All 12 Lines | def test_load(self): | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'HEAD': { | 'HEAD': { | ||||
'target': 'releases/1.3.0', | 'target': 'releases/1.3.0', | ||||
'target_type': 'alias', | 'target_type': 'alias', | ||||
}, | }, | ||||
} | } | ||||
self.assertSnapshotOk(expected_snapshot_id, expected_branches) | self.assertSnapshotEqual(expected_snapshot_id, expected_branches) | ||||
_id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | _id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | ||||
self.assertNotEqual(expected_snapshot_id, _id) | self.assertNotEqual(expected_snapshot_id, _id) | ||||
self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | ||||
self.assertEqual(self.loader.visit_status(), 'full') | self.assertEqual(self.loader.visit_status(), 'full') | ||||
class PyPILoaderWithSnapshot2(TestPyPILoader): | class PyPILoaderWithSnapshot2(PyPILoaderTest): | ||||
"""This loader provides a snapshot and lists corresponding seen | """This loader provides a snapshot and lists corresponding seen | ||||
release artifacts. | release artifacts. | ||||
""" | """ | ||||
def _last_snapshot(self): | def _last_snapshot(self): | ||||
"""Return last visited snapshot""" | """Return last visited snapshot""" | ||||
return { | return { | ||||
'id': b'\x072"\t\xe5\x16\x18A\x0b^C\xcaJ\xf7\xe0O\xe5\x11<\x9d', # noqa | 'id': b'\x072"\t\xe5\x16\x18A\x0b^C\xcaJ\xf7\xe0O\xe5\x11<\x9d', # noqa | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | class LoaderChangesOldReleaseArtifactRemovedSinceLastVisit(PyPIBaseLoaderTest): | ||||
""" | """ | ||||
def setUp(self, project_name='0805nexter', | def setUp(self, project_name='0805nexter', | ||||
dummy_pypi_instance='https://dummy.org'): | dummy_pypi_instance='https://dummy.org'): | ||||
super().setUp(project_name, dummy_pypi_instance) | super().setUp(project_name, dummy_pypi_instance) | ||||
self.loader = PyPILoaderWithSnapshot2( | self.loader = PyPILoaderWithSnapshot2( | ||||
project_name=project_name, | project_name=project_name, | ||||
json_filename='0805nexter-unpublished-release.json') | json_filename='0805nexter-unpublished-release.json') | ||||
self.storage = self.loader.storage | |||||
def test_load(self): | def test_load(self): | ||||
"""Load PyPI origin with removed artifact + changes ~> 1 new snapshot | """Load PyPI origin with removed artifact + changes ~> 1 new snapshot | ||||
""" | """ | ||||
# when | # when | ||||
self.loader.load( | self.loader.load( | ||||
self._project, self._origin_url, self._project_metadata_url) | self._project, self._origin_url, self._project_metadata_url) | ||||
Show All 11 Lines | def test_load(self): | ||||
expected_contents = [ | expected_contents = [ | ||||
'e2d68a197e3a3ad0fc6de28749077892c2148043', # new one | 'e2d68a197e3a3ad0fc6de28749077892c2148043', # new one | ||||
'405859113963cb7a797642b45f171d6360425d16', | '405859113963cb7a797642b45f171d6360425d16', | ||||
'83ecf6ec1114fd260ca7a833a2d165e71258c338', | '83ecf6ec1114fd260ca7a833a2d165e71258c338', | ||||
'e5686aa568fdb1d19d7f1329267082fe40482d31', | 'e5686aa568fdb1d19d7f1329267082fe40482d31', | ||||
] | ] | ||||
self.assertContentsOk(expected_contents) | self.assertContentsContain(expected_contents) | ||||
expected_directories = [ | expected_directories = [ | ||||
'a2b7621f3e52eb3632657f6e3436bd08202db56f', # new one | 'a2b7621f3e52eb3632657f6e3436bd08202db56f', # new one | ||||
'770e21215ecac53cea331d8ea4dc0ffc9d979367', | '770e21215ecac53cea331d8ea4dc0ffc9d979367', | ||||
] | ] | ||||
self.assertDirectoriesOk(expected_directories) | self.assertDirectoriesContain(expected_directories) | ||||
expected_revisions = { | expected_revisions = { | ||||
# 1.4.0 | # 1.4.0 | ||||
'5e91875f096ac48c98d74acf307439a3490f2827': '770e21215ecac53cea331d8ea4dc0ffc9d979367', # noqa | '5e91875f096ac48c98d74acf307439a3490f2827': '770e21215ecac53cea331d8ea4dc0ffc9d979367', # noqa | ||||
} | } | ||||
self.assertRevisionsOk(expected_revisions) | self.assertRevisionsContain(expected_revisions) | ||||
expected_snapshot_id = 'bb0b0c29040678eadb6dae9e43e496cc860123e4' | expected_snapshot_id = 'bb0b0c29040678eadb6dae9e43e496cc860123e4' | ||||
expected_branches = { | expected_branches = { | ||||
'releases/1.2.0': { | 'releases/1.2.0': { | ||||
'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | 'target': 'e445da4da22b31bfebb6ffc4383dbf839a074d21', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'releases/1.3.0': { | 'releases/1.3.0': { | ||||
'target': 'fb46e49605b0bbe69f8c53d315e89370e7c6cb5d', | 'target': 'fb46e49605b0bbe69f8c53d315e89370e7c6cb5d', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'releases/1.4.0': { | 'releases/1.4.0': { | ||||
'target': '5e91875f096ac48c98d74acf307439a3490f2827', | 'target': '5e91875f096ac48c98d74acf307439a3490f2827', | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
}, | }, | ||||
'HEAD': { | 'HEAD': { | ||||
'target': 'releases/1.4.0', | 'target': 'releases/1.4.0', | ||||
'target_type': 'alias', | 'target_type': 'alias', | ||||
}, | }, | ||||
} | } | ||||
self.assertSnapshotOk(expected_snapshot_id, expected_branches) | self.assertSnapshotEqual(expected_snapshot_id, expected_branches) | ||||
_id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | _id = hashutil.hash_to_hex(self.loader._last_snapshot()['id']) | ||||
self.assertNotEqual(expected_snapshot_id, _id) | self.assertNotEqual(expected_snapshot_id, _id) | ||||
self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) | ||||
self.assertEqual(self.loader.visit_status(), 'full') | self.assertEqual(self.loader.visit_status(), 'full') |
also override it (see D684)