diff --git a/debian/control b/debian/control --- a/debian/control +++ b/debian/control @@ -12,10 +12,10 @@ python3-setuptools, python3-subvertpy (>= 0.9.4~), python3-swh.core (>= 0.0.19~), - python3-swh.loader.core (>= 0.0.35~), + python3-swh.loader.core (>= 0.0.36~), python3-swh.model (>= 0.0.18~), python3-swh.scheduler (>= 0.0.14~), - python3-swh.storage (>= 0.0.83~), + python3-swh.storage (>= 0.0.114~), python3-vcversioner, subversion Standards-Version: 3.9.6 @@ -25,10 +25,10 @@ Architecture: all Depends: gzip, python3-swh.core (>= 0.0.19~), - python3-swh.loader.core (>= 0.0.35~), + python3-swh.loader.core (>= 0.0.36~), python3-swh.model (>= 0.0.18~), python3-swh.scheduler (>= 0.0.14~), - python3-swh.storage (>= 0.0.83~), + python3-swh.storage (>= 0.0.114~), subversion, ${misc:Depends}, ${python3:Depends} diff --git a/requirements-swh.txt b/requirements-swh.txt --- a/requirements-swh.txt +++ b/requirements-swh.txt @@ -1,5 +1,5 @@ swh.core >= 0.0.19 -swh.storage >= 0.0.83 +swh.storage >= 0.0.114 swh.model >= 0.0.18 swh.scheduler >= 0.0.14 -swh.loader.core >= 0.0.35 +swh.loader.core >= 0.0.36 diff --git a/swh/loader/svn/tests/test_loader.py b/swh/loader/svn/tests/test_loader.py --- a/swh/loader/svn/tests/test_loader.py +++ b/swh/loader/svn/tests/test_loader.py @@ -6,7 +6,7 @@ import os from unittest import TestCase -from swh.loader.core.tests import BaseLoaderTest, LoaderNoStorage +from swh.loader.core.tests import BaseLoaderTest from swh.loader.svn.loader import (DEFAULT_BRANCH, SvnLoader, SvnLoaderFromRemoteDump, build_swh_snapshot) from swh.model import hashutil @@ -18,11 +18,16 @@ In its setup, it's uncompressing a local svn mirror to /tmp. """ - def setUp(self, archive_name='pkg-gourmet.tgz', filename='pkg-gourmet'): + def setUp(self, archive_name='pkg-gourmet.tgz', filename='pkg-gourmet', + loader=None): super().setUp(archive_name=archive_name, filename=filename, prefix_tmp_folder_name='swh.loader.svn.', start_path=os.path.dirname(__file__)) self.svn_mirror_url = self.repo_url + self.loader = loader + if not loader: + self.loader = SvnLoaderMemoryStorage() + self.storage = self.loader.storage class TestSnapshot(TestCase): @@ -40,6 +45,31 @@ }) +_LOADER_TEST_CONFIG = { + 'check_revision': {'limit': 100, 'status': False}, + 'content_packet_block_size_bytes': 104857600, + 'content_packet_size': 10000, + 'content_packet_size_bytes': 1073741824, + 'content_size_limit': 104857600, + 'debug': False, + 'directory_packet_size': 2500, + 'log_db': 'dbname=softwareheritage-log', + 'occurrence_packet_size': 1000, + 'release_packet_size': 1000, + 'revision_packet_size': 10, + 'save_data': False, + 'save_data_path': '', + 'send_contents': True, + 'send_directories': True, + 'send_occurrences': True, + 'send_releases': True, + 'send_revisions': True, + 'send_snapshot': True, + 'storage': {'args': {}, 'cls': 'memory'}, + 'temp_directory': '/tmp/swh.loader.svn' +} + + class LoaderWithState: """Additional state setup (bypassed by some override for test purposes) @@ -56,8 +86,11 @@ 'visit': 1, } + def parse_config_file(self, *args, **kwargs): + return _LOADER_TEST_CONFIG + -class SvnLoaderNoStorage(LoaderNoStorage, LoaderWithState, SvnLoader): +class SvnLoaderMemoryStorage(LoaderWithState, SvnLoader): """An SVNLoader with no persistence. Context: @@ -71,7 +104,7 @@ return {} -class SvnLoaderUpdateNoStorage(LoaderNoStorage, LoaderWithState, SvnLoader): +class SvnLoaderUpdateMemoryStorage(LoaderWithState, SvnLoader): """An SVNLoader with no persistence. Context: @@ -93,7 +126,10 @@ """ return { - 'snapshot': 'something', # need a snapshot of sort + 'snapshot': { + 'id': 'something', + 'branches': {} + }, # need a snapshot of sort 'revision': { 'id': hashutil.hash_to_bytes( '4876cb10aec6f708f7466dddf547567b65f6c39c'), @@ -113,8 +149,8 @@ } -class SvnLoaderUpdateHistoryAlteredNoStorage(LoaderNoStorage, LoaderWithState, - SvnLoader): +class SvnLoaderUpdateHistoryAlteredMemoryStorage(LoaderWithState, + SvnLoader): """Context: Load a known svn repository using the swh policy with its history altered so we do not update it. @@ -156,7 +192,6 @@ """ def setUp(self): super().setUp() - self.loader = SvnLoaderNoStorage() def test_load(self): """Load a new repository results in new swh object and snapshot @@ -184,7 +219,7 @@ last_revision: '0deab3023ac59398ae467fc4bff5583008af1ee2', # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -198,8 +233,7 @@ """ def setUp(self): - super().setUp() - self.loader = SvnLoaderUpdateNoStorage() + super().setUp(loader=SvnLoaderUpdateMemoryStorage()) def test_load(self): """Load a repository without new changes results in same snapshot @@ -233,8 +267,8 @@ """ def setUp(self): # the svn repository pkg-gourmet has been updated with changes - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderUpdateHistoryAlteredNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderUpdateHistoryAlteredMemoryStorage()) def test_load(self): """Load known repository with history altered should do nothing @@ -266,8 +300,8 @@ """ def setUp(self): # the svn repository pkg-gourmet has been updated with changes - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderUpdateNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderUpdateMemoryStorage()) def test_process_repository(self): """Process updated repository should yield new objects @@ -295,7 +329,7 @@ last_revision: 'fd24a76c87a3207428e06612b49860fc78e9f6dc' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state @@ -313,8 +347,8 @@ """ def setUp(self): # the svn repository pkg-gourmet has been updated with changes - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderUpdateNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderUpdateMemoryStorage()) def test_load(self): """Load an existing repository from scratch yields same swh objects @@ -346,7 +380,7 @@ '171dc35522bfd17dda4e90a542a0377fb2fc707a': 'fd24a76c87a3207428e06612b49860fc78e9f6dc', # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state @@ -355,8 +389,8 @@ self.assertEqual(self.loader.visit_status(), 'full') -class SvnLoaderWithPreviousRevisionNoStorage(LoaderNoStorage, LoaderWithState, - SvnLoader): +class SvnLoaderWithPreviousRevisionMemoryStorage(LoaderWithState, + SvnLoader): """An SVNLoader with no persistence. Context: Load a known svn repository using the swh policy with its @@ -400,8 +434,8 @@ """ def setUp(self): - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderWithPreviousRevisionNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderWithPreviousRevisionMemoryStorage()) def test_load(self): """Load from partial previous visit result in new changes @@ -430,7 +464,7 @@ last_revision: 'fd24a76c87a3207428e06612b49860fc78e9f6dc' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -446,8 +480,8 @@ """ def setUp(self): - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderUpdateNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderUpdateMemoryStorage()) def test_load(self): """Load known and partial repository should start from last visit @@ -493,7 +527,7 @@ last_revision: 'fd24a76c87a3207428e06612b49860fc78e9f6dc' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -501,8 +535,8 @@ self.assertEqual(self.loader.visit_status(), 'full') -class SvnLoaderUpdateLessRecentNoStorage(LoaderNoStorage, LoaderWithState, - SvnLoader): +class SvnLoaderUpdateLessRecentMemoryStorage(LoaderWithState, + SvnLoader): """Context: Load a known svn repository. The last visit seen is less recent than a previous unfinished crawl. @@ -547,8 +581,8 @@ """ def setUp(self): - super().setUp(archive_name='pkg-gourmet-with-updates.tgz') - self.loader = SvnLoaderUpdateLessRecentNoStorage() + super().setUp(archive_name='pkg-gourmet-with-updates.tgz', + loader=SvnLoaderUpdateLessRecentMemoryStorage()) def test_load(self): """Load repository should yield revisions starting from last visit @@ -593,7 +627,7 @@ last_revision: 'fd24a76c87a3207428e06612b49860fc78e9f6dc' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -610,8 +644,8 @@ """ def setUp(self): super().setUp(archive_name='mediawiki-repo-r407-eol-native-crlf.tgz', - filename='mediawiki-repo-r407-eol-native-crlf') - self.loader = SvnLoaderNoStorage() + filename='mediawiki-repo-r407-eol-native-crlf', + loader=SvnLoaderMemoryStorage()) def test_process_repository(self): """Load repository with CRLF endings (svn:eol-style: native) is ok @@ -624,7 +658,7 @@ expected_revisions = { '7da4975c363101b819756d33459f30a866d01b1b': 'f63637223ee0f7d4951ffd2d4d9547a4882c5d8b' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -643,8 +677,8 @@ def setUp(self): super().setUp( archive_name='pyang-repo-r343-eol-native-mixed-lf-crlf.tgz', - filename='pyang-repo-r343-eol-native-mixed-lf-crlf') - self.loader = SvnLoaderNoStorage() + filename='pyang-repo-r343-eol-native-mixed-lf-crlf', + loader=SvnLoaderMemoryStorage()) def test_load(self): """Load repo with mixed CRLF/LF endings (svn:eol-style:native) is ok @@ -657,7 +691,7 @@ '9c6962eeb9164a636c374be700672355e34a98a7': '16aa6b6271f3456d4643999d234cf39fe3d0cc5a' # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state # self.assertEqual(self.loader.all_snapshots[0], {}) @@ -673,8 +707,8 @@ """ def setUp(self): - super().setUp(archive_name='pkg-gourmet-with-external-id.tgz') - self.loader = SvnLoaderNoStorage() + super().setUp(archive_name='pkg-gourmet-with-external-id.tgz', + loader=SvnLoaderMemoryStorage()) def test_load(self): """Repository with svn:externals property, will stop raising an error @@ -720,7 +754,7 @@ } # The last revision being the one used later to start back from - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) @@ -736,8 +770,8 @@ """ def setUp(self): super().setUp( - archive_name='pkg-gourmet-with-edge-case-links-and-files.tgz') - self.loader = SvnLoaderNoStorage() + archive_name='pkg-gourmet-with-edge-case-links-and-files.tgz', + loader=SvnLoaderMemoryStorage()) def test_load(self): """File/Link removed prior to folder with same name creation is ok @@ -779,7 +813,7 @@ last_revision: '6b1e0243768ff9ac060064b2eeade77e764ffc82', # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) @@ -794,8 +828,8 @@ """ def setUp(self): super().setUp( - archive_name='pkg-gourmet-with-wrong-link-cases.tgz') - self.loader = SvnLoaderNoStorage() + archive_name='pkg-gourmet-with-wrong-link-cases.tgz', + loader=SvnLoaderMemoryStorage()) def test_load(self): """Wrong link or empty space-named link should be ok @@ -837,15 +871,15 @@ last_revision: 'd853d9628f6f0008d324fed27dadad00ce48bc62', # noqa } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) self.assertCountSnapshots(1) # FIXME: Check the snapshot's state self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) self.assertEqual(self.loader.visit_status(), 'full') -class SvnLoaderFromRemoteDumpNoStorage(LoaderNoStorage, LoaderWithState, - SvnLoaderFromRemoteDump): +class SvnLoaderFromRemoteDumpMemoryStorage(LoaderWithState, + SvnLoaderFromRemoteDump): """A SvnLoaderFromRemoteDump with no persistence. Context: @@ -866,26 +900,28 @@ and the base svn loader are the same. """ def setUp(self): - super().setUp(archive_name='pkg-gourmet.tgz') + super().setUp(archive_name='pkg-gourmet.tgz', + loader=SvnLoaderFromRemoteDumpMemoryStorage()) def test_load(self): """ Compare results of remote dump loader and base loader """ - dump_loader = SvnLoaderFromRemoteDumpNoStorage() + dump_loader = self.loader dump_loader.load(svn_url=self.svn_mirror_url) - base_loader = SvnLoaderNoStorage() + self.assertCountContents(19) + self.assertCountDirectories(17) + self.assertCountRevisions(6) + self.assertCountSnapshots(1) + + base_loader = SvnLoaderMemoryStorage() base_loader.load(svn_url=self.svn_mirror_url) - self.assertEqual(dump_loader.state('content'), - base_loader.state('content')) - self.assertEqual(dump_loader.state('directory'), - base_loader.state('directory')) - self.assertEqual(dump_loader.state('revision'), - base_loader.state('revision')) - self.assertEqual(dump_loader.state('snapshot'), - base_loader.state('snapshot')) + dump_storage_stat = dump_loader.storage.stat_counters() + base_storage_stat = base_loader.storage.stat_counters() + + self.assertEqual(dump_storage_stat, base_storage_stat) class SvnLoaderITTest14(BaseSvnLoaderTest): @@ -895,8 +931,8 @@ """ def setUp(self): - super().setUp(archive_name='httthttt.tgz', filename='httthttt') - self.loader = SvnLoaderNoStorage() + super().setUp(archive_name='httthttt.tgz', filename='httthttt', + loader=SvnLoaderMemoryStorage()) def test_load(self): """Decoding user defined svn properties error should not fail loading @@ -922,7 +958,7 @@ last_revision: 'f051d60256b2d89a0ca2704d6f91ad1b0ab44e02', } - self.assertRevisionsOk(expected_revisions) + self.assertRevisionsContain(expected_revisions) expected_snapshot_id = '70487267f682c07e52a2371061369b6cf5bffa47' expected_branches = { @@ -932,7 +968,7 @@ } } - self.assertSnapshotOk(expected_snapshot_id, expected_branches) + self.assertSnapshotEqual(expected_snapshot_id, expected_branches) self.assertEqual(self.loader.load_status(), {'status': 'eventful'}) self.assertEqual(self.loader.visit_status(), 'full')