def run_migration(cls, plan): """Run a migration using simple plan.""" mp = cls.migration_plans_api.create({'plan': plan}) mp_run_response = cls.migration_plans_api.run(mp.pulp_href, {}) task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group) return task
def _do_test(self, repos, migration_plan): mp = self.migration_plans_api.create({'plan': migration_plan}) mp_run_response = self.migration_plans_api.run(mp.pulp_href, {}) task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group) for repo_id in repos: pulp3repos = self.file_repo_api.list(name=repo_id) # Assert that there is a result self.failIf( not pulp3repos.results, "Missing a Pulp 3 repository for Pulp 2 " "repository id '{}'".format(repo_id)) repo_href = pulp3repos.results[0].pulp_href # Assert that the name in pulp 3 matches the repo_id in pulp 2 self.assertEqual(repo_id, pulp3repos.results[0].name) # Assert that there is a Repository Version with the same number of content units as # associated with the repository in Pulp 2. repo_version_href = self.file_repo_versions_api.list( repo_href).results[0].pulp_href repo_version_content = self.file_content_api.list( repository_version=repo_version_href) self.assertEqual(PULP_2_ISO_FIXTURE_DATA[repo_id], repo_version_content.count) # TODO: count only not_in_plan=False repositories from ../pulp2repositories/ endpoint self.assertEqual(len(repos), self.file_repo_api.list().count)
def test_serving_acs_content(self): """Test serving of ACS content through the content app.""" cfg = config.get_config() acs = self._create_acs() resp = self.file_acs_api.refresh(acs.pulp_href, acs) monitor_task_group(resp.task_group) remote = self.file_remote_api.create( gen_file_remote(FILE_MANIFEST_ONLY_FIXTURE_URL, policy="on_demand") ) self.addCleanup(self.file_remote_api.delete, remote.pulp_href) repo = self.repo_api.create(gen_repo(remote=remote.pulp_href, autopublish=True)) self.addCleanup(self.repo_api.delete, repo.pulp_href) distribution_response = self.distribution_api.create( gen_distribution(repository=repo.pulp_href) ) created_resources = monitor_task(distribution_response.task).created_resources distribution = self.distribution_api.read(created_resources[0]) self.addCleanup(self.distribution_api.delete, distribution.pulp_href) repository_sync_data = RepositorySyncURL(remote=remote.pulp_href) sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) monitor_task(sync_response.task) repo = self.repo_api.read(repo.pulp_href) unit_path = choice(get_file_content_paths(repo.to_dict())) fixtures_hash = hashlib.sha256( utils.http_get(urljoin(FILE_FIXTURE_URL, unit_path)) ).hexdigest() content = download_content_unit(cfg, distribution.to_dict(), unit_path) pulp_hash = hashlib.sha256(content).hexdigest() self.assertEqual(fixtures_hash, pulp_hash)
def _load_and_run(self, plan, run_params={}): """Load and run a migration plan.""" mp = self.migration_plans_api.create({'plan': plan}) mp_run_response = self.migration_plans_api.run(mp.pulp_href, run_params) task = monitor_task(mp_run_response.task) # to ensure that migration fully finished and further tests won't collide with it monitor_task_group(task.task_group) return task
def test_run_only_one_plan(self): """Test that only one plan can be run at a time""" mp = self.migration_plans_api.create({'plan': FILE_SIMPLE_PLAN}) # run twice mp_run_response = self.migration_plans_api.run(mp.pulp_href, {}) with self.assertRaises(ApiException): self.migration_plans_api.run(mp.pulp_href, {}) # make sure the first task is completed not to interfere with further tests task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group)
def test_no_reset_when_migration(self): """Test that reset is not run when migration is.""" mp = self.migration_plans_api.create({"plan": FILE_SIMPLE_PLAN}) # run the migration plan and then immediately run reset without waiting mp_run_response = self.migration_plans_api.run(mp.pulp_href, {}) with self.assertRaises(ApiException): self.migration_plans_api.reset(mp.pulp_href) # make sure the first task is completed not to interfere with further tests task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group)
def _perform_import(self, importer, chunked=False, an_export=None): """Perform an import with importer.""" if not an_export: an_export = self.chunked_export if chunked else self.export if chunked: filenames = [ f for f in list(an_export.output_file_info.keys()) if f.endswith("json") ] import_response = self.imports_api.create(importer.pulp_href, {"toc": filenames[0]}) else: filenames = [ f for f in list(an_export.output_file_info.keys()) if f.endswith("tar.gz") ] import_response = self.imports_api.create(importer.pulp_href, {"path": filenames[0]}) monitor_task(import_response.task) task = self.client.get(import_response.task) resources = task["created_resources"] task_group_href = resources[1] task_group = monitor_task_group(task_group_href) return task_group
def _do_test_parallel(self, plan, outcome): """Test that there were multiple tasks running in parallel as a part of a task group.""" mp = self.migration_plans_api.create({'plan': plan}) mp_run_response = self.migration_plans_api.run(mp.pulp_href, {}) task = monitor_task(mp_run_response.task) group = monitor_task_group(task.task_group) self.assertEqual(group.completed, outcome)
def test_run_only_one_plan(self): """Test that only one plan can be run at a time""" mp = self.migration_plans_api.create({'plan': FILE_SIMPLE_PLAN}) # run twice mp_run_response = self.migration_plans_api.run(mp.pulp_href, {}) with self.assertRaises(ApiException): self.migration_plans_api.run(mp.pulp_href, {}) # TODO: we should do more specific checks but for now I get empty exc for this call # TODO: self.assertEqual(exc.code, 400) # TODO: self.assertEqual(exc.exception.msg, ONLY_ONE_PLAN_ERROR) # make sure the first task is completed not to interfere with further tests task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group)
def run_migration(cls, plan, run_params={}): """ Run a migration plan. Args: plan(str): A migration plan to run, in JSON format. run_params(dict): parameters for the `run` call. Optional. Returns: task(pulpcore.app.models.Task): a migration task created for this plan """ mp = cls.migration_plans_api.create({"plan": plan}) mp_run_response = cls.migration_plans_api.run(mp.pulp_href, run_params) task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group) return task
def do_test(self, acs_url, paths, remote_url): """Sync with ACS test.""" # ACS is rpm-unsigned repository which has all packages needed acs_remote = self.remote_api.create( gen_rpm_remote(url=acs_url, policy="on_demand")) self.addCleanup(self.remote_api.delete, acs_remote.pulp_href) acs_data = { "name": "alternatecontentsource", "remote": acs_remote.pulp_href, "paths": paths, } acs = self.acs_api.create(acs_data) self.addCleanup(self.acs_api.delete, acs.pulp_href) repo = self.repo_api.create(gen_repo()) self.addCleanup(self.repo_api.delete, repo.pulp_href) remote = self.remote_api.create(gen_rpm_remote(url=remote_url)) self.addCleanup(self.remote_api.delete, remote.pulp_href) # Sync repo with metadata only, before ACS refresh it should fail repository_sync_data = RpmRepositorySyncURL(remote=remote.pulp_href) with self.assertRaises(PulpTaskError) as ctx: sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) monitor_task(sync_response.task) self.assertIn("404, message='Not Found'", ctx.exception.task.error["description"]) # ACS refresh acs_refresh = self.acs_api.refresh(acs.pulp_href, acs) monitor_task_group(acs_refresh.task_group) # Sync repository with metadata only sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) monitor_task(sync_response.task) return self.repo_api.read(repo.pulp_href)
def test_acs_sync(self): """Test syncing from an ACS.""" repo = self.repo_api.create(gen_repo()) self.addCleanup(self.repo_api.delete, repo.pulp_href) remote = self.file_remote_api.create(gen_file_remote(FILE_MANIFEST_ONLY_FIXTURE_URL)) self.addCleanup(self.file_remote_api.delete, remote.pulp_href) repository_sync_data = RepositorySyncURL(remote=remote.pulp_href) # sync should fail as the repo has metadata only (no files) sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) with self.assertRaises(PulpTaskError) as ctx: monitor_task(sync_response.task) self.assertIn("404", ctx.exception.task.error["description"]) # create an acs and pull in its remote artifacts acs = self._create_acs() resp = self.file_acs_api.refresh(acs.pulp_href, acs) monitor_task_group(resp.task_group) # the sync should now work as the files are being pulled from ACS remote sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) monitor_task(sync_response.task)
def test_acs_sync_with_paths(self): """Test syncing from an ACS using different paths.""" repo = self.repo_api.create(gen_repo()) self.addCleanup(self.repo_api.delete, repo.pulp_href) remote = self.file_remote_api.create(gen_file_remote(FILE_MANIFEST_ONLY_FIXTURE_URL)) self.addCleanup(self.file_remote_api.delete, remote.pulp_href) acs = self._create_acs( paths=("file/PULP_MANIFEST", "file2/PULP_MANIFEST"), remote_url=PULP_FIXTURES_BASE_URL, ) resp = self.file_acs_api.refresh(acs.pulp_href, acs) task_group = monitor_task_group(resp.task_group) self.assertEquals(len(task_group.tasks), 2) repository_sync_data = RepositorySyncURL(remote=remote.pulp_href) sync_response = self.repo_api.sync(repo.pulp_href, repository_sync_data) monitor_task(sync_response.task)
def _perform_import(self, importer, chunked=False): """Perform an import with importer.""" if chunked: filenames = [ f for f in list(self.chunked_export.output_file_info.keys()) if f.endswith("json") ] import_response = self.imports_api.create(importer.pulp_href, {"toc": filenames[0]}) else: filenames = [ f for f in list(self.export.output_file_info.keys()) if f.endswith("tar.gz") ] import_response = self.imports_api.create(importer.pulp_href, {"path": filenames[0]}) task_group = monitor_task_group(import_response.task_group) return task_group
def test_clean_import(self): """Test an import into an empty instance.""" # By the time we get here, setUpClass() has created repos and an export for us # Find the export file, create the importer, delete repos/export, and then let # the import happen filenames = [f for f in list(self.export.output_file_info.keys()) if f.endswith("tar.gz")] importer = self._create_importer() self._post_export_cleanup() # At this point we should be importing into a content-free-zone import_response = self.imports_api.create(importer.pulp_href, {"path": filenames[0]}) monitor_task(import_response.task) task = self.client.get(import_response.task) resources = task["created_resources"] task_group_href = resources[1] task_group = monitor_task_group(task_group_href) self.assertEqual(len(self.import_repos) + 1, task_group.completed) for repo in self.import_repos: repo = self.repo_api.read(repo.pulp_href) self.assertEqual(f"{repo.pulp_href}versions/1/", repo.latest_version_href)
def _run_migration(self, migration_plan): """Run a migration task and wait for it to be complete.""" mp_run_response = self.migration_plans_api.run(migration_plan.pulp_href, {}) task = monitor_task(mp_run_response.task) monitor_task_group(task.task_group)
def test_import_export(self): """ Test exporting and importing of a container repository. """ core_client = CoreApiClient(configuration) container_client = ContainerApiClient(configuration) remotes_api = RemotesContainerApi(container_client) repositories_api = RepositoriesContainerApi(container_client) repository_versions_api = RepositoriesContainerVersionsApi( container_client) manifests_api = ContentManifestsApi(container_client) exporters_api = ExportersPulpApi(core_client) exports_api = ExportersPulpExportsApi(core_client) importers_api = ImportersPulpApi(core_client) imports_api = ImportersPulpImportsApi(core_client) # Setup remote = remotes_api.create(gen_container_remote()) self.addCleanup(remotes_api.delete, remote.pulp_href) sync_data = ContainerRepositorySyncURL(remote=remote.pulp_href) repository = repositories_api.create(gen_repo()) self.addCleanup(repositories_api.delete, repository.pulp_href) sync_response = repositories_api.sync(repository.pulp_href, sync_data) monitor_task(sync_response.task).created_resources # Export the repository body = { "name": uuid4(), "path": "/tmp/{}/".format(uuid4()), "repositories": [repository.pulp_href], } exporter = exporters_api.create(body) self.addCleanup(exporters_api.delete, exporter.pulp_href) export_response = exports_api.create(exporter.pulp_href, {}) export_href = monitor_task(export_response.task).created_resources[0] export = exports_api.read(export_href) # Clean the old repository out monitor_task( repository_versions_api.delete( repository.latest_version_href).task) delete_orphans() # Import the repository import_repository = repositories_api.create(gen_repo()) self.addCleanup(repositories_api.delete, import_repository.pulp_href) body = { "name": uuid4(), "repo_mapping": { repository.name: import_repository.name }, } importer = importers_api.create(body) self.addCleanup(importers_api.delete, importer.pulp_href) filenames = [ f for f in list(export.output_file_info.keys()) if f.endswith("tar.gz") ] import_response = imports_api.create(importer.pulp_href, {"path": filenames[0]}) if hasattr(import_response, "task_group"): task_group_href = import_response.task_group else: task_group_href = monitor_task( import_response.task).created_resources[1] monitor_task_group(task_group_href) # Verify that the imported repository contains the right associations import_repository = repositories_api.read(import_repository.pulp_href) manifests = manifests_api.list( repository_version=import_repository.latest_version_href).results for manifest in manifests: if "manifest.list" in manifest.media_type: self.assertNotEqual(manifest.listed_manifests, []) else: self.assertNotEqual(manifest.blobs, []) self.assertIsNotNone(manifest.config_blob)