Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Added migraiton plan tests
Browse files Browse the repository at this point in the history
Also switched to using the renamed pulp2 snapshot.

closes #7934
https://pulp.plan.io/issues/7934
  • Loading branch information
goosemania committed Dec 11, 2020
1 parent 2af25d8 commit c94b8bb
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,8 @@ jobs:
docker logs pulp || true
docker exec pulp ls -latr /etc/yum.repos.d/ || true
docker exec pulp cat /etc/yum.repos.d/* || true
# - name: After failure - Setup Tmate
# if: failure()
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 60
1 change: 1 addition & 0 deletions CHANGES/7934.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added migration plan tests.
56 changes: 56 additions & 0 deletions pulp_2to3_migration/tests/functional/common_plans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Migration plans which are used by many different tests.
"""

import json


FILE_COMPLEX_PLAN = json.dumps({
"plugins": [{
"type": "iso",
"repositories": [
{
"name": "file",
"pulp2_importer_repository_id": "file", # policy: immediate
"repository_versions": [
{
"pulp2_repository_id": "file", # content count: iso - 3
"pulp2_distributor_repository_ids": ["file"]
}
]
},
{
"name": "file2",
"pulp2_importer_repository_id": "file2", # policy: on_demand
"repository_versions": [
{
"pulp2_repository_id": "file2", # content count: iso - 3
"pulp2_distributor_repository_ids": ["file2"]
}
]
},
{
"name": "file-large",
"pulp2_importer_repository_id": "file-large", # policy: immediate
"repository_versions": [
{
"pulp2_repository_id": "file-large", # content count: iso - 10
"pulp2_distributor_repository_ids": ["file-large"]
}
]
},
{
"name": "file-many",
"pulp2_importer_repository_id": "file-many", # policy: on_demand
"repository_versions": [
{
"pulp2_repository_id": "file-many", # content count: iso - 250
"pulp2_distributor_repository_ids": ["file-many"]
}
]
},
]
}]
})

FILE_SIMPLE_PLAN = json.dumps({"plugins": [{"type": "iso"}]})
2 changes: 1 addition & 1 deletion pulp_2to3_migration/tests/functional/scripts/set_pulp2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ cp -r pulp-2to3-migration-test-fixtures/${ARCHIVE_NAME}/var/lib/pulp/content /va
cp -r pulp-2to3-migration-test-fixtures/${ARCHIVE_NAME}/var/lib/pulp/published /var/lib/pulp/

mongo --host ${MONGO_HOST} pulp_database --eval 'db.dropDatabase();'
mongorestore --host ${MONGO_HOST} --archive=pulp-2to3-migration-test-fixtures/${ARCHIVE_NAME}/pulp2filecontent.${ARCHIVE_NAME}.archive --drop
mongorestore --host ${MONGO_HOST} --archive=pulp-2to3-migration-test-fixtures/${ARCHIVE_NAME}/mongodb.${ARCHIVE_NAME}.archive --drop
4 changes: 3 additions & 1 deletion pulp_2to3_migration/tests/functional/test_file_migration.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import time
import unittest

from pulpcore.client.pulpcore import (
Expand Down Expand Up @@ -124,14 +125,15 @@ def setUpClass(cls):
cls.tasks_api = TasksApi(core_client)
cls.migration_plans_api = MigrationPlansApi(migration_client)

set_pulp2_snapshot(name='20191031')
set_pulp2_snapshot(name='file_base_4repos')

def tearDown(self):
"""
Clean up the database after each test
"""
cmd = get_psql_smash_cmd(TRUNCATE_TABLES_QUERY_BASH)
self.smash_cli_client.run(cmd, sudo=True)
time.sleep(0.5)

def _do_test(self, repos, migration_plan):
mp = self.migration_plans_api.create({'plan': migration_plan})
Expand Down
169 changes: 169 additions & 0 deletions pulp_2to3_migration/tests/functional/test_migration_plan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import json
import unittest

from pulpcore.client.pulpcore import (
ApiClient as CoreApiClient,
Configuration,
TasksApi
)
from pulpcore.client.pulp_file import (
ApiClient as FileApiClient,
ContentFilesApi,
RepositoriesFileApi,
RepositoriesFileVersionsApi
)
from pulpcore.client.pulp_2to3_migration import (
ApiClient as MigrationApiClient,
MigrationPlansApi
)
from pulpcore.client.pulp_2to3_migration.exceptions import ApiException

from pulp_2to3_migration.tests.functional.util import get_psql_smash_cmd, set_pulp2_snapshot

from pulp_smash import cli
from pulp_smash import config as smash_config
from pulp_smash.pulp3.bindings import monitor_task, monitor_task_group, PulpTaskError

from .common_plans import FILE_SIMPLE_PLAN, FILE_COMPLEX_PLAN
from .constants import TRUNCATE_TABLES_QUERY_BASH


EXTRA_COMMA_PLAN = '{"plugins": [{"type": "iso"},]}'
MISSING_RESOURCE_PLAN = json.dumps({
"plugins": [{
"type": "iso",
"repositories": [
{
"name": "file",
"pulp2_importer_repository_id": "non-existing importer", # policy: immediate
"repository_versions": [
{
"pulp2_repository_id": "non-existing repo", # content count: iso - 3
"pulp2_distributor_repository_ids": ["non-existing distributor"]
}
]
}
]
}]
})
MISSING_RESOURCE_ERROR = 'Validation failed: resources missing '\
'{\'repositories\': [\'non-existing repo\'], '\
'\'repositories_missing_importers\': [\'non-existing importer\'], '\
'\'repositories_missing_distributors\': [\'non-existing distributor\']}'
# ONLY_ONE_PLAN_ERROR = 'Only one migration plan can run or be reset at a time'
UNKNOWN_KEY_PLAN = json.dumps({"plugins": [{"type": "iso", "unknown key": "value"}]})


class TestMigrationPlan(unittest.TestCase):
"""Test the Migration Plan creation and validation"""

smash_cfg = smash_config.get_config()
smash_cli_client = cli.Client(smash_cfg)

@classmethod
def setUpClass(cls):
"""
Create all the client instances needed to communicate with Pulp.
"""
configuration = Configuration()
configuration.username = 'admin'
configuration.password = 'password'
configuration.host = 'http://pulp'
configuration.safe_chars_for_path_param = '/'

core_client = CoreApiClient(configuration)
file_client = FileApiClient(configuration)
migration_client = MigrationApiClient(configuration)

# Create api clients for all resource types
cls.file_repo_api = RepositoriesFileApi(file_client)
cls.file_repo_versions_api = RepositoriesFileVersionsApi(file_client)
cls.file_content_api = ContentFilesApi(file_client)
cls.tasks_api = TasksApi(core_client)
cls.migration_plans_api = MigrationPlansApi(migration_client)

set_pulp2_snapshot(name='file_base_4repos')

@classmethod
def tearDownClass(cls):
"""
Clean up the database after the set of tests is run.
"""
cmd = get_psql_smash_cmd(TRUNCATE_TABLES_QUERY_BASH)
cls.smash_cli_client.run(cmd, sudo=True)

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 _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_load_simple_plan(self):
"""Test that a simple Migration Plan can be loaded and run."""
self._load_and_run(FILE_SIMPLE_PLAN)

def test_load_complex_plan(self):
"""Test that a complex Migration Plan can be loaded and run."""
self._load_and_run(FILE_COMPLEX_PLAN)

@unittest.skip('not fixed yet, https://pulp.plan.io/issues/7948')
def test_load_extra_comma_plan(self):
"""Test that a proper exception is risen when there is a syntax error in a plan."""
with self.assertRaises(ApiException) as exc:
self.migration_plans_api.create({'plan': EXTRA_COMMA_PLAN})
self.assertEqual(exc.code, 400)

def test_unknown_key_plan(self):
"""Test that Migration Plan creation fails if some unknown keys are mentioned in it."""
with self.assertRaises(ApiException) as exc:
self.migration_plans_api.create({'plan': UNKNOWN_KEY_PLAN})
self.assertEqual(exc.code, 400)

def test_validate_plan(self):
"""Test that pulp 2 resources are validated."""
self._load_and_run(FILE_COMPLEX_PLAN, {'validate': True})

def test_validate_missing_resource(self):
"""Test that pulp 2 missing resource is noticed and reported."""
mp = self.migration_plans_api.create({'plan': MISSING_RESOURCE_PLAN})
mp_run_response = self.migration_plans_api.run(mp.pulp_href, {'validate': True})
with self.assertRaises(PulpTaskError) as exc:
monitor_task(mp_run_response.task)
self.assertEqual(exc.exception.task.error['description'], MISSING_RESOURCE_ERROR)

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)

@unittest.skip('not fixed yet, https://pulp.plan.io/issues/6516')
def test_simple_plan_parallel(self):
"""Test that using a simple plan, there is work which is performed in parallel."""
self._do_test_parallel(FILE_SIMPLE_PLAN, 5)

def test_complex_plan_parallel(self):
"""Test that using a complex plan, there is work which is performed in parallel."""
self._do_test_parallel(FILE_COMPLEX_PLAN, 5)

0 comments on commit c94b8bb

Please sign in to comment.