def test_positive_promote_valid_environment(self): """@Test: Promote a content view version to 'next in sequence' lifecycle environment. @Assert: Promotion succeeds. @Feature: Content View Version """ # Create a new content view... cv = entities.ContentView(organization=self.org).create() # ... and promote it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version self.assertEqual(len(cv.version), 1) version = cv.version[0].read() # Assert that content view version is found in 1 lifecycle # environments (i.e. 'Library') self.assertEqual(len(version.environment), 1) # Promote it to the next 'in sequence' lifecycle environment promote(version, self.lce1.id) # Assert that content view version is found in 2 lifecycle # environments. version = version.read() self.assertEqual(len(version.environment), 2)
def test_positive_promote_with_puppet_once(self): """@Test: Give content view a puppet module. Publish and promote it once @Assert: The content view has one puppet module, the content view version is in ``Library + 1`` lifecycle environments and it has one puppet module assigned too. @Feature: ContentView """ content_view = entities.ContentView(organization=self.org).create() puppet_module = random.choice( content_view.available_puppet_modules()['results'] ) entities.ContentViewPuppetModule( author=puppet_module['author'], name=puppet_module['name'], content_view=content_view, ).create() content_view.publish() content_view = content_view.read() lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.puppet_module), 1) cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), 2) self.assertEqual(len(cvv.puppet_module), 1)
def test_positive_promote_multiple_with_docker_repo(self): """Add Docker-type repository to content view and publish it. Then promote it to multiple available lifecycle-environments. @Assert: Docker-type repository is promoted to content view found in the specific lifecycle-environments. @Feature: Docker """ repo = _create_repository( entities.Product(organization=self.org).create()) content_view = entities.ContentView( composite=False, organization=self.org, ).create() content_view.repository = [repo] content_view = content_view.update(['repository']) self.assertEqual( [repo.id], [repo_.id for repo_ in content_view.repository]) content_view.publish() cvv = content_view.read().version[0] self.assertEqual(len(cvv.read().environment), 1) for i in range(1, randint(3, 6)): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(cvv, lce.id) self.assertEqual(len(cvv.read().environment), i+1)
def test_positive_add_host(session): """Check if host can be added to Host Collection :id: 80824c9f-15a1-4f76-b7ac-7d9ca9f6ed9e :expectedresults: Host is added to Host Collection successfully :CaseLevel: System """ hc_name = gen_string('alpha') org = entities.Organization().create() cv = entities.ContentView(organization=org).create() lce = entities.LifecycleEnvironment(organization=org).create() cv.publish() promote(cv.read().version[0], lce.id) host = entities.Host( organization=org, content_facet_attributes={ 'content_view_id': cv.id, 'lifecycle_environment_id': lce.id, }, ).create() with session: session.organization.select(org_name=org.name) session.hostcollection.create({'name': hc_name}) assert session.hostcollection.search(hc_name)[0]['Name'] == hc_name session.hostcollection.associate_host(hc_name, host.name) hc_values = session.hostcollection.read(hc_name) assert ( hc_values['hosts']['resources']['assigned'][0]['Name'] == host.name )
def test_positive_content_view_history(self): """Check if the Content View History are working in the Dashboard UI :id: cb63a67d-7cca-4d2c-9abf-9f4f5e92c856 :Steps: 1. Navigate to Monitor -> Dashboard 2. Review the Content View History widget :expectedresults: Each Content View link shows its current status (the environment to which it is published) :CaseLevel: Integration """ org = entities.Organization().create() lc_env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() content_view.publish() promote(content_view.read().version[0], lc_env.id) expected_list = [ ['Promoted to {0}'.format(lc_env.name), 'Success'], ['Published new version', 'Success'] ] with Session(self.browser) as session: set_context(session, org=org.name) actual_list = self.dashboard.get_cvh_tasks_list(content_view.name) self.assertTrue(all( element in exp_element for sublist, exp_sublist in zip(expected_list, actual_list) for element, exp_element in zip(sublist, exp_sublist) ))
def test_positive_update_cv(self): """Update a hostgroup with a new content view @id: 5fa39bc9-c780-49c5-b580-b973e2d25226 @assert: A hostgroup is updated with expected content view @CaseLevel: Integration """ content_view = entities.ContentView(organization=self.org).create() content_view.publish() content_view = content_view.read() lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) hostgroup = entities.HostGroup( content_view=content_view, lifecycle_environment=lce, location=[self.loc], organization=[self.org], ).create() new_cv = entities.ContentView(organization=self.org).create() new_cv.publish() new_cv = new_cv.read() promote(new_cv.version[0], lce.id) hostgroup.content_view = new_cv hostgroup = hostgroup.update(['content_view']) self.assertEqual(hostgroup.content_view.read().name, new_cv.name)
def test_positive_promote_composite_single_content_multiple(self): """Create empty composite view and assign one normal content view to it. After that promote that composite content view ``Library + random`` times. @id: ba3b737c-365a-4a7b-9109-e6d52fd1c31f @Assert: Composite content view version points to ``Library + random`` lifecycle environments after the promotions. @CaseLevel: Integration """ composite_cv = entities.ContentView( composite=True, organization=self.org, ).create() self.add_content_views_to_composite(composite_cv) composite_cv.publish() composite_cv = composite_cv.read() envs_amount = random.randint(3, 5) for _ in range(envs_amount): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(composite_cv.version[0], lce.id) composite_cv = composite_cv.read() self.assertEqual(len(composite_cv.version), 1) self.assertEqual( envs_amount + 1, len(composite_cv.version[0].read().environment), )
def test_positive_promote_valid_environment(self): """Promote a content view version to 'next in sequence' lifecycle environment. :id: f205ca06-8ab5-4546-83bd-deac4363d487 :expectedresults: Promotion succeeds. :CaseLevel: Integration """ # Create a new content view... cv = entities.ContentView(organization=self.org).create() # ... and promote it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version self.assertEqual(len(cv.version), 1) version = cv.version[0].read() # Assert that content view version is found in 1 lifecycle # environments (i.e. 'Library') self.assertEqual(len(version.environment), 1) # Promote it to the next 'in sequence' lifecycle environment promote(version, self.lce1.id) # Assert that content view version is found in 2 lifecycle # environments. version = version.read() self.assertEqual(len(version.environment), 2)
def test_positive_add_host(self): """Check if host can be added to Host Collection @id: 80824c9f-15a1-4f76-b7ac-7d9ca9f6ed9e @Assert: Host is added to Host Collection successfully @CaseLevel: System """ name = gen_string('alpha') cv = entities.ContentView(organization=self.organization).create() lce = entities.LifecycleEnvironment( organization=self.organization).create() cv.publish() promote(cv.read().version[0], lce.id) new_system = make_fake_host({ u'content-view-id': cv.id, u'lifecycle-environment-id': lce.id, u'name': gen_string('alpha'), u'organization-id': self.organization.id, }) with Session(self.browser) as session: make_host_collection( session, org=self.organization.name, name=name) self.hostcollection.add_host(name, new_system['name'])
def test_positive_promote_out_of_sequence(self): """Try to publish content view few times in a row and then re-promote first version to default environment @id: 40d20aba-726f-48e3-93b7-fb1ab1851ac7 @Assert: Content view promoted out of sequence properly @CaseLevel: Integration """ content_view = entities.ContentView(organization=self.org).create() for _ in range(REPEAT): content_view.publish() content_view = content_view.read() # Check that CV is published and has proper number of CV versions. self.assertEqual(len(content_view.version), REPEAT) # After each publish operation application re-assign environment to # latest CV version. Correspondingly, at that moment, first cv version # should have 0 environments and latest should have one ('Library') # assigned to it. self.assertEqual(len(content_view.version[0].read().environment), 0) lce_list = content_view.version[-1].read().environment self.assertEqual(len(lce_list), 1) # Trying to re-promote 'Library' environment from latest version to # first one promote(content_view.version[0], lce_list[0].id, force=True) content_view = content_view.read() # Verify that, according to our plan, first version contains one # environment and latest - 0 self.assertEqual(len(content_view.version[0].read().environment), 1) self.assertEqual(len(content_view.version[-1].read().environment), 0)
def test_positive_promote_out_of_sequence_environment(self): """Promote a content view version to a lifecycle environment that is 'out of sequence'. :id: e88405de-843d-4279-9d81-cedaab7c23cf :expectedresults: The promotion succeeds. :CaseLevel: Integration """ # Create a new content view... cv = entities.ContentView(organization=self.org).create() # ... and publish it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version self.assertEqual(len(cv.version), 1) version = cv.version[0].read() # The immediate lifecycle is lce1, not lce2 promote(version, self.lce2.id, force=True) # Assert that content view version is found in 2 lifecycle # environments. version = version.read() self.assertEqual(len(version.environment), 2)
def test_positive_delete_non_default(self): """Create content view and publish and promote it to new environment. After that try to disassociate content view from 'Library' and one more non-default environments through 'delete_from_environment' command and delete content view version from that content view. :id: 95bb973c-ebec-4a72-a1b6-ad28b66bd11b :expectedresults: Content view version deleted successfully :CaseLevel: Integration """ org = entities.Organization().create() content_view = entities.ContentView(organization=org).create() # Publish content view content_view.publish() content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.version[0].read().environment), 1) lce = entities.LifecycleEnvironment(organization=org).create() promote(content_view.version[0], lce.id) cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), 2) # Delete the content-view version from selected environments for env in reversed(cvv.environment): content_view.delete_from_environment(env.id) content_view.version[0].delete() # Make sure that content view version is really removed self.assertEqual(len(content_view.read().version), 0)
def test_positive_rendering_after_env_removed(self): """Check if Dashboard UI rendered properly after lc environment for active organization is removed from the system :id: 81c52395-3476-4123-bc3b-49d6c658da9a :Steps: 1. Create an environment (e.g. Dev) 2. Create a content view and promote it to the environment 3. Remove the environment. 4. Visit the dashboard page and verify that it loads successfully. :expectedresults: Dashboard search box and necessary widgets are rendered before and after necessary environment is removed :BZ: 1361793 :CaseLevel: Integration """ org = entities.Organization().create() lc_env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() content_view.publish() promote(content_view.read().version[0], lc_env.id) with Session(self.browser) as session: set_context(session, org=org.name) self.assertIsNotNone( self.dashboard.search(lc_env.name, 'lifecycle_environment')) entities.LifecycleEnvironment(id=lc_env.id).delete() self.assertIsNotNone( self.dashboard.search(lc_env.name, 'lifecycle_environment')) self.assertIsNotNone( self.dashboard.get_widget('Content View History'))
def test_positive_sync_publish_promote_cv(self): """Synchronize repository with DRPMs, add repository to content view, publish and promote content view to lifecycle environment @id: 44296354-8ca2-4ce0-aa16-398effc80d9c @Assert: drpms can be listed in content view in proper lifecycle environment """ lce = entities.LifecycleEnvironment(organization=self.org).create() repo = entities.Repository( product=self.product, url=FAKE_YUM_DRPM_REPO, ).create() repo.sync() cv = entities.ContentView(organization=self.org).create() cv.repository = [repo] cv.update(['repository']) cv.publish() cv = cv.read() promote(cv.version[0], lce.id) result = ssh.command( 'ls /var/lib/pulp/published/yum/https/repos/{}/{}/{}/custom/{}/{}' '/drpms/ | grep .drpm' .format( self.org.label, lce.name, cv.label, self.product.label, repo.label, ) ) self.assertEqual(result.return_code, 0) self.assertGreaterEqual(len(result.stdout), 1)
def test_positive_promote_composite_multiple_content_multiple(self): """@Test: Create empty composite view and assign random number of normal content views to it. After that promote that composite content view ``Library + random`` times. @Assert: Composite content view version points to ``Library + random`` lifecycle environments after the promotions. @Feature: ContentView """ composite_cv = entities.ContentView( composite=True, organization=self.org, ).create() self.add_content_views_to_composite(composite_cv, random.randint(3, 5)) composite_cv.publish() composite_cv = composite_cv.read() envs_amount = random.randint(3, 5) for _ in range(envs_amount): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(composite_cv.version[0], lce.id) composite_cv = composite_cv.read() self.assertEqual(len(composite_cv.version), 1) self.assertEqual( envs_amount + 1, len(composite_cv.version[0].read().environment), )
def test_positive_remove_docker_repo_ccv(self): """Add Docker-type repository to a non-composite content view and publish it. Then add this content view to a composite content view and publish it. Create an activation key and associate it with the composite Docker content view. Then, remove the composite content view from the activation key. @Assert: Docker-based composite content view can be added and then removed from the activation key. @Feature: Docker """ comp_content_view = entities.ContentView( composite=True, organization=self.org, ).create() comp_content_view.component = [self.cvv] comp_content_view = comp_content_view.update(['component']) self.assertEqual(self.cvv.id, comp_content_view.component[0].id) comp_content_view.publish() comp_cvv = comp_content_view.read().version[0].read() promote(comp_cvv, self.lce.id) ak = entities.ActivationKey( content_view=comp_content_view, environment=self.lce, organization=self.org, ).create() self.assertEqual(ak.content_view.id, comp_content_view.id) ak.content_view = None self.assertIsNone(ak.update(['content_view']).content_view)
def test_pre_user_scenario_capsule_sync(self): """Pre-upgrade scenario that creates and sync repository with rpm in satellite which will be synced in post upgrade scenario. :id: preupgrade-eb8970fa-98cc-4a99-99fb-1c12c4e319c9 :steps: 1. Before Satellite upgrade, Sync a repo/rpm in satellite :expectedresults: The repo/rpm should be synced to satellite """ ak = entities.ActivationKey(organization=self.org_id).search( query={'search': 'name={}'.format(self.activation_key)})[0] ak_env = ak.environment.read() product = entities.Product( name=self.prod_name, organization=self.org_id).create() self.create_repo() repo = entities.Repository( product=product.id, name=self.repo_name, url=self.repo_url).create() repo.sync() content_view = entities.ContentView( name=self.cv_name, organization=self.org_id).create() content_view.repository = [repo] content_view = content_view.update(['repository']) content_view.publish() promote(content_view.read().version[0], ak_env.id) self.assertEqual(content_view.read().environment[-1].id, ak_env.id) global_dict = {self.__class__.__name__: { 'env_name': ak_env.name}} create_dict(global_dict)
def test_positive_promote_with_yum_multiple(self): """@Test: Give a content view a yum repo, publish it once and promote the content view version ``REPEAT + 1`` times. @Assert: The content view has one repository, the content view version is in ``REPEAT + 1`` lifecycle environments and it has at least one package. @Feature: ContentView """ content_view = entities.ContentView(organization=self.org).create() content_view.repository = [self.yum_repo] content_view.update(['repository']) content_view.publish() content_view = content_view.read() # Promote the content view version. for _ in range(REPEAT): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) # Everything's done - check some content view attributes... content_view = content_view.read() self.assertEqual(len(content_view.repository), 1) self.assertEqual(len(content_view.version), 1) # ...and some content view version attributes. cvv_attrs = content_view.version[0].read_json() self.assertEqual(len(cvv_attrs['environments']), REPEAT + 1) self.assertGreater(cvv_attrs['package_count'], 0)
def test_promote_cv_with_puppet_multiple(self): """@Test: Give a content view a puppet module, publish it once and promote the content view version ``Library + random`` times. @Assert: The content view has one puppet module, the content view version is in ``Library + random`` lifecycle environments and it has one puppet module. @Feature: ContentView """ content_view = entities.ContentView(organization=self.org).create() puppet_module = random.choice(content_view.available_puppet_modules()["results"]) entities.ContentViewPuppetModule( author=puppet_module["author"], name=puppet_module["name"], content_view=content_view ).create() content_view.publish() content_view = content_view.read() # Promote the content view version. envs_amount = random.randint(3, 5) for _ in range(envs_amount): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) # Everything's done. Check some content view attributes... content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.puppet_module), 1) # ...and some content view version attributes. cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), envs_amount + 1) self.assertEqual(len(cvv.puppet_module), 1)
def test_positive_content_view_history(session): """Check if the Content View History are working in the Dashboard UI :id: cb63a67d-7cca-4d2c-9abf-9f4f5e92c856 :Steps: 1. Navigate to Monitor -> Dashboard 2. Review the Content View History widget :expectedresults: Each Content View link shows its current status (the environment to which it is published) :CaseLevel: Integration """ org = entities.Organization().create() lc_env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() content_view.publish() promote(content_view.read().version[0], lc_env.id) with session: session.organization.select(org_name=org.name) cv_values = session.dashboard.read('ContentViews') assert content_view.name in cv_values[ 'content_views'][0]['Content View'] assert cv_values['content_views'][0][ 'Task'] == 'Promoted to {0}'.format(lc_env.name) assert 'Success' in cv_values['content_views'][0]['Status'] assert content_view.name in cv_values[ 'content_views'][1]['Content View'] assert cv_values['content_views'][1]['Task'] == 'Published new version' assert 'Success' in cv_values['content_views'][1]['Status']
def test_promote_docker_repo_content_view(self): """@Test: Add Docker-type repository to content view and publish it. Then promote it to the next available lifecycle-environment. @Assert: Docker-type repository is promoted to content view found in the specific lifecycle-environment. @Feature: Docker """ lce = entities.LifecycleEnvironment(organization=self.org).create() repo = _create_repository( entities.Product(organization=self.org).create()) content_view = entities.ContentView( composite=False, organization=self.org, ).create() content_view.repository = [repo] content_view = content_view.update(['repository']) self.assertEqual( [repo.id], [repo_.id for repo_ in content_view.repository]) content_view.publish() content_view = content_view.read() cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), 1) promote(cvv, lce.id) self.assertEqual(len(cvv.read().environment), 2)
def test_delete_version_non_default(self): """@Test: Create content view and publish and promote it to new environment. After that try to disassociate content view from 'Library' and one more non-default environments through 'delete_from_environment' command and delete content view version from that content view. @Assert: Content view version deleted successfully @Feature: ContentViewVersion """ org = entities.Organization().create() content_view = entities.ContentView(organization=org).create() # Publish content view content_view.publish() content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.version[0].read().environment), 1) lce = entities.LifecycleEnvironment(organization=org).create() promote(content_view.version[0], lce.id) cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), 2) # Delete the content-view version from selected environments for env in reversed(cvv.environment): content_view.delete_from_environment(env.id) content_view.version[0].delete() # Make sure that content view version is really removed self.assertEqual(len(content_view.read().version), 0)
def test_negative_promote_valid_environment(self): """@Test: Promote the default content view version. @Assert: The promotion fails. @Feature: ContentViewVersion """ with self.assertRaises(HTTPError): promote(self.default_cv, self.lce1.id)
def test_negative_promote_2(self): """@Test: Promote a content view version using an invalid environment. @Assert: The promotion fails. @Feature: ContentViewVersion """ with self.assertRaises(HTTPError): promote(entities.ContentViewVersion(id=1), -1)
def test_positive_sort_by_hostgroup(self): """Create some Host entities and sort them by host group ascendingly and then descendingly :id: d1ac744a-ff76-4afe-84a1-3a7e4b3ca3f1 :customerscenario: true :expectedresults: Host entities are sorted properly :CaseImportance: High :BZ: 1268085 :CaseLevel: Integration """ org = entities.Organization().create() lce = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() content_view.publish() content_view = content_view.read() promote(content_view.version[0], environment_id=lce.id) name_list = [gen_string('alpha', 20) for _ in range(5)] host = entities.Host(organization=org) host.create_missing() for name in name_list: hg = entities.HostGroup(name=name, organization=[org]).create() entities.Host( hostgroup=hg, organization=org, architecture=host.architecture, domain=host.domain, environment=host.environment, content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': lce.id, }, location=host.location, mac=host.mac, medium=host.medium, operatingsystem=host.operatingsystem, ptable=host.ptable, root_pass=host.root_pass, ).create() with Session(self) as session: set_context(session, org=org.name) self.hosts.navigate_to_entity() self.assertEqual( self.hosts.sort_table_by_column('Host group'), sorted(name_list, key=six.text_type.lower) ) self.assertEqual( self.hosts.sort_table_by_column('Host group'), sorted(name_list, key=six.text_type.lower, reverse=True) )
def test_negative_promote_1(self): """@Test: Promote the default content view version. @Assert: The promotion fails. @Feature: ContentViewVersion """ env = entities.Environment().create() with self.assertRaises(HTTPError): promote(entities.ContentViewVersion(id=1), env.id)
def test_negative_promote_valid_environment(self): """Promote the default content view version. :id: cd4f3c3d-93c5-425f-bc3b-d1ac17696a4a :expectedresults: The promotion fails. :CaseLevel: Integration """ with self.assertRaises(HTTPError): promote(self.default_cv, self.lce1.id)
def test_positive_filter_by_environment(session, module_org, module_repos_col): """Filter Content hosts by environment :id: 578c3a92-c4d8-4933-b122-7ff511c276ec :customerscenario: true :BZ: 1383729 :Setup: Errata synced on satellite server. :Steps: Go to Content -> Errata. Select an Errata -> Content Hosts tab -> Filter content hosts by Environment. :expectedresults: Content hosts can be filtered by Environment. :CaseLevel: System """ with VirtualMachine(distro=module_repos_col.distro) as client1, VirtualMachine( distro=module_repos_col.distro) as client2: for client in client1, client2: module_repos_col.setup_virtual_machine(client) assert _install_client_package( client, FAKE_1_CUSTOM_PACKAGE, errata_applicability=True) # Promote the latest content view version to a new lifecycle environment content_view = entities.ContentView( id=module_repos_col.setup_content_data['content_view']['id']).read() content_view_version = content_view.version[-1].read() lce = content_view_version.environment[-1].read() new_lce = entities.LifecycleEnvironment(organization=module_org, prior=lce).create() promote(content_view_version, new_lce.id) host = entities.Host().search( query={'search': 'name={0}'.format(client1.hostname)})[0].read() host.content_facet_attributes = { 'content_view_id': content_view.id, 'lifecycle_environment_id': new_lce.id, } host.update(['content_facet_attributes']) with session: # search in new_lce values = session.errata.search_content_hosts( CUSTOM_REPO_ERRATA_ID, client1.hostname, environment=new_lce.name) assert values[0]['Name'] == client1.hostname assert not session.errata.search_content_hosts( CUSTOM_REPO_ERRATA_ID, client2.hostname, environment=new_lce.name) # search in lce values = session.errata.search_content_hosts( CUSTOM_REPO_ERRATA_ID, client2.hostname, environment=lce.name) assert values[0]['Name'] == client2.hostname assert not session.errata.search_content_hosts( CUSTOM_REPO_ERRATA_ID, client1.hostname, environment=lce.name)
def test_post_user_scenario_capsule_sync_2(self): """Post-upgrade scenario that creates and sync repository with rpm, sync capsule with satellite and verifies if the repo/rpm in satellite is synced to capsule. :id: postupgrade-7c1d3441-3e8d-4ac2-8102-30e18274658c :steps: 1. Post Upgrade , Sync a repo/rpm in satellite. 2. Run capsule sync. 3. Check if the repo/rpm is been synced to capsule. :expectedresults: 1. The repo/rpm should be synced to satellite 2. Capsule sync should be successful 3. The repo/rpm from satellite should be synced to capsule """ ak = entities.ActivationKey(organization=self.org_id).search( query={'search': 'name={}'.format(self.activation_key)})[0] ak_env = ak.environment.read() product = entities.Product( name=self.prod_name, organization=self.org_id).create() self.create_repo() repo = entities.Repository( product=product.id, name=self.repo_name, url=self.repo_url).create() repo.sync() content_view = entities.ContentView( name=self.cv_name, organization=self.org_id).create() content_view.repository = [repo] content_view = content_view.update(['repository']) content_view.publish() promote(content_view.read().version[0], ak_env.id) self.assertEqual(content_view.read().environment[-1].id, ak_env.id) wait_untill_capsule_sync(self.cap_host) org_name = entities.Organization().search( query={'search': 'id={}'.format(self.org_id)})[0].label result = execute( lambda: run( '[ -f /var/lib/pulp/published/yum/http/repos/' '{0}/{1}/{2}/custom/{3}/{4}/Packages/c/{5} ]; echo $?'.format( org_name, ak_env.name, self.cv_name, self.prod_name, self.repo_name, self.rpm_name)), host=self.cap_host )[self.cap_host] self.assertEqual('0', result)
def setUpClass(cls): """Create necessary objects which can be re-used in tests.""" super(DockerActivationKeyTestCase, cls).setUpClass() cls.org = entities.Organization().create() cls.lce = entities.LifecycleEnvironment(organization=cls.org).create() cls.repo = _create_repository( entities.Product(organization=cls.org).create()) content_view = entities.ContentView( composite=False, organization=cls.org, ).create() content_view.repository = [cls.repo] cls.content_view = content_view.update(['repository']) cls.content_view.publish() cls.cvv = content_view.read().version[0].read() promote(cls.cvv, cls.lce.id)
def test_positive_update_content_source_id( module_org, module_location, module_lce, module_published_cv ): """Read the host content_source_id attribute from the update request response :id: d47214d2-a54c-4385-abfb-a0607ecb6ec7 :customerscenario: true :expectedresults: content_source_id is present in PUT host request response :BZ: 1339613, 1488130 :CaseLevel: System """ proxy = entities.SmartProxy().search( query={'url': f'https://{settings.server.hostname}:9090'} )[0] promote(module_published_cv.version[0], environment_id=module_lce.id) host = entities.Host( organization=module_org, location=module_location, content_facet_attributes={ 'content_view_id': module_published_cv.id, 'lifecycle_environment_id': module_lce.id, }, ).create() host.content_facet_attributes['content_source_id'] = proxy.id # we need to ensure that content_source_id is returned by PUT request, # we will use entity update_json as entity update method will invoke # read method after PUT request completion response = host.update_json(['content_facet_attributes']) content_facet_attributes = response.get('content_facet_attributes') assert content_facet_attributes is not None content_source_id = content_facet_attributes.get('content_source_id') assert content_source_id is not None assert content_source_id == proxy.id
def test_positive_promote_with_docker_repo_composite(self): """Add Docker-type repository to content view and publish it. Then add that content view to composite one. Publish and promote that composite content view to the next available lifecycle-environment. :id: e903c7b2-7722-4a9e-bb69-99bbd3c23946 :expectedresults: Docker-type repository is promoted to content view found in the specific lifecycle-environment. """ lce = entities.LifecycleEnvironment(organization=self.org).create() repo = _create_repository( entities.Product(organization=self.org).create()) content_view = entities.ContentView( composite=False, organization=self.org, ).create() content_view.repository = [repo] content_view = content_view.update(['repository']) self.assertEqual([repo.id], [repo_.id for repo_ in content_view.repository]) content_view.publish() cvv = content_view.read().version[0].read() comp_content_view = entities.ContentView( composite=True, organization=self.org, ).create() comp_content_view.component = [cvv] comp_content_view = comp_content_view.update(['component']) self.assertEqual(cvv.id, comp_content_view.component[0].id) comp_content_view.publish() comp_cvv = comp_content_view.read().version[0] self.assertEqual(len(comp_cvv.read().environment), 1) promote(comp_cvv, lce.id) self.assertEqual(len(comp_cvv.read().environment), 2)
def test_positive_name_pattern_change(self): """Promote content view with Docker repository to lifecycle environment. Change registry name pattern for that environment. Verify that repository name on product changed according to new pattern. :id: cc78d82d-027b-4cb7-92c5-dcccf9b592ea :expectedresults: Container repository name is changed according to new pattern. """ pattern_prefix = gen_string('alpha', 5) docker_upstream_name = 'hello-world' new_pattern = ( "{}-<%= organization.label %>" "/<%= repository.docker_upstream_name %>").format(pattern_prefix) repo = _create_repository( entities.Product(organization=self.org).create(), upstream_name=docker_upstream_name) repo.sync() content_view = entities.ContentView( composite=False, organization=self.org, ).create() content_view.repository = [repo] content_view = content_view.update(['repository']) content_view.publish() cvv = content_view.read().version[0] lce = entities.LifecycleEnvironment(organization=self.org).create() promote(cvv, lce.id) lce.registry_name_pattern = new_pattern lce = lce.update(['registry_name_pattern']) repos = entities.Repository(organization=self.org).search( query={'environment_id': lce.id}) expected_pattern = "{}-{}/{}".format(pattern_prefix, self.org.label, docker_upstream_name).lower() self.assertEqual(lce.registry_name_pattern, new_pattern) self.assertEqual(repos[0].container_repository_name, expected_pattern)
def test_positive_content_host_previous_env(session, module_org, module_repos_col, vm): """Check if the applicable errata are available from the content host's previous environment :id: 78110ba8-3942-46dd-8c14-bffa1dbd5195 :Setup: 1. Make sure multiple environments are present. 2. Content host's previous environments have additional errata. :Steps: Go to Content Hosts -> Select content host -> Errata Tab -> Select Previous environments. :expectedresults: The errata from previous environments are displayed. :CaseLevel: System """ host_name = vm.hostname assert _install_client_package(vm, FAKE_1_CUSTOM_PACKAGE, errata_applicability=True) # Promote the latest content view version to a new lifecycle environment content_view = entities.ContentView( id=module_repos_col.setup_content_data['content_view']['id']).read() content_view_version = content_view.version[-1].read() lce = content_view_version.environment[-1].read() new_lce = entities.LifecycleEnvironment(organization=module_org, prior=lce).create() promote(content_view_version, new_lce.id) host = entities.Host().search(query={'search': 'name={0}'.format(host_name)})[0].read() host.content_facet_attributes = { 'content_view_id': content_view.id, 'lifecycle_environment_id': new_lce.id, } host.update(['content_facet_attributes']) with session: environment = 'Previous Lifecycle Environment ({0}/{1})'.format( lce.name, content_view.name) content_host_erratum = session.contenthost.search_errata( host_name, CUSTOM_REPO_ERRATA_ID, environment=environment) assert content_host_erratum[0]['Id'] == CUSTOM_REPO_ERRATA_ID
def test_negative_promote_out_of_sequence_environment(self): """Promote a content view version to a lifecycle environment that is 'out of sequence'. :id: 621d1bb6-92c6-4209-8369-6ea14a4c8a01 :expectedresults: The promotion fails. :CaseLevel: Integration """ # Create a new content view... cv = entities.ContentView(organization=self.org).create() # ... and publish it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version self.assertEqual(len(cv.version), 1) version = cv.version[0].read() # The immediate lifecycle is lce1, not lce2 with self.assertRaises(HTTPError): promote(version, self.lce2.id)
def test_positive_create_with_cv(self): """Create a hostgroup with content view specified :id: 43dfd2e9-68fe-4682-9cac-61c622c11126 :expectedresults: A hostgroup is created with expected content view assigned :CaseLevel: Integration """ content_view = entities.ContentView(organization=self.org).create() content_view.publish() content_view = content_view.read() lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) hostgroup = entities.HostGroup( content_view=content_view, lifecycle_environment=lce, location=[self.loc], organization=[self.org], ).create() self.assertEqual(hostgroup.content_view.read().name, content_view.name)
def test_positive_promote_rh_custom_spin(self): """Attempt to promote a content view containing Red Hat spin - i.e., contains filters. @Feature: Content Views @Assert: Content view can be promoted """ content_view = entities.ContentView(organization=self.org).create() content_view.repository = [self.repo] content_view = content_view.update(['repository']) entities.RPMContentViewFilter( content_view=content_view, inclusion='true', name=gen_string('alphanumeric'), ).create() content_view.publish() lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.read().version[0], lce.id) self.assertEqual( len(content_view.read().version[0].read().environment), 2)
def test_positive_subscribe_system(self): """Subscribe a system to a content view. @Feature: ContentView @Assert: It is possible to create a system and set its 'content_view_id' attribute. """ # organization # ├── lifecycle environment # └── content view org = entities.Organization().create() lc_env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() # Publish the content view. content_view.publish() content_view = content_view.read() # Promote the content view version. self.assertEqual(len(content_view.version), 1) promote(content_view.version[0], lc_env.id) # Create a system that is subscribed to the published and promoted # content view. Associating this system with the organization and # environment created above is not particularly important, but doing so # means a shorter test where fewer entities are created, as # System.organization and System.environment are required attributes. system = entities.System( content_view=content_view, environment=lc_env, organization=org, ).create() # See BZ #1151240 self.assertEqual(system.content_view.id, content_view.id) self.assertEqual(system.environment.id, lc_env.id) if not bz_bug_is_open(1223494): self.assertEqual(system.organization.id, org.id)
def test_positive_add_docker_repo_cv(session, module_org): """Add docker repository to a non-composite content view and publish it. Then create an activation key and associate it with the Docker content view. :id: e4935729-c5bc-46be-a23a-93ebde6b3506 :expectedresults: Content view with docker repo can be added to activation key :CaseLevel: Integration """ lce = entities.LifecycleEnvironment(organization=module_org).create() repo = entities.Repository( content_type=REPO_TYPE['docker'], product=entities.Product(organization=module_org).create(), url=DOCKER_REGISTRY_HUB, ).create() content_view = entities.ContentView( composite=False, organization=module_org, repository=[repo], ).create() content_view.publish() cvv = content_view.read().version[0].read() promote(cvv, lce.id) ak_name = gen_string('alphanumeric') with session: session.activationkey.create({ 'name': ak_name, 'lce': { lce.name: True }, 'content_view': content_view.name, }) ak = session.activationkey.read(ak_name, 'details') assert ak['details']['content_view'] == content_view.name assert ak['details']['lce'][lce.name][lce.name]
def setup_content(request): org = entities.Organization().create() with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhst7']['name'], reposet=REPOSET['rhst7'], releasever=None, ) rh_repo = entities.Repository(id=rh_repo_id).read() rh_repo.sync() custom_repo = entities.Repository( product=entities.Product(organization=org).create(), ).create() custom_repo.sync() lce = entities.LifecycleEnvironment(organization=org).create() cv = entities.ContentView( organization=org, repository=[rh_repo_id, custom_repo.id], ).create() cv.publish() cvv = cv.read().version[0].read() promote(cvv, lce.id) ak = entities.ActivationKey(content_view=cv, max_hosts=100, organization=org, environment=lce, auto_attach=True).create() subscription = entities.Subscription(organization=org).search( query={'search': 'name="{}"'.format(DEFAULT_SUBSCRIPTION_NAME)})[0] ak.add_subscriptions(data={ 'quantity': 1, 'subscription_id': subscription.id }) request.cls.org_setup = org request.cls.ak_setup = ak
def test_negative_promote_out_of_sequence_environment(module_lce_cv, module_org): """Attempt to promote a content view version to a Lifecycle environment that is 'out of sequence'. :id: 621d1bb6-92c6-4209-8369-6ea14a4c8a01 :expectedresults: The promotion fails. :CaseLevel: Integration """ # Create a new content view... cv = entities.ContentView(organization=module_org).create() # ... and publish it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version assert len(cv.version) == 1 version = cv.version[0].read() # The immediate lifecycle is lce1, not lce2 with pytest.raises(HTTPError): promote(version, module_lce_cv[1].id)
def test_positive_promote_out_of_sequence_environment(self): """Promote a content view version to a lifecycle environment that is 'out of sequence'. @Assert: The promotion succeeds. @Feature: Content View Version """ # Create a new content view... cv = entities.ContentView(organization=self.org).create() # ... and publish it. cv.publish() # Refresh the entity cv = cv.read() # Check that we have a new version self.assertEqual(len(cv.version), 1) version = cv.version[0].read() # The immediate lifecycle is lce1, not lce2 promote(version, self.lce2.id, force=True) # Assert that content view version is found in 2 lifecycle # environments. version = version.read() self.assertEqual(len(version.environment), 2)
def test_positive_read_content_source_id( module_org, module_location, module_lce, module_published_cv ): """Read the host content_source_id attribute from the read request response :id: 0a7fd8d4-1ea8-4b21-8c46-10579644fd11 :customerscenario: true :expectedresults: content_source_id is present in GET host request response :BZ: 1339613, 1488130 :CaseLevel: System """ proxy = ( entities.SmartProxy() .search(query={'url': f'https://{settings.server.hostname}:9090'})[0] .read() ) promote(module_published_cv.version[0], environment_id=module_lce.id) host = entities.Host( organization=module_org, location=module_location, content_facet_attributes={ 'content_source_id': proxy.id, 'content_view_id': module_published_cv.id, 'lifecycle_environment_id': module_lce.id, }, ).create() content_facet_attributes = getattr(host, 'content_facet_attributes') assert content_facet_attributes is not None content_source_id = content_facet_attributes.get('content_source_id') assert content_source_id is not None assert content_source_id == proxy.id
def test_positive_promote_with_puppet_multiple(self): """Give a content view a puppet module, publish it once and promote the content view version ``Library + random`` times. @Assert: The content view has one puppet module, the content view version is in ``Library + random`` lifecycle environments and it has one puppet module. @Feature: ContentView """ content_view = entities.ContentView(organization=self.org).create() puppet_module = random.choice( content_view.available_puppet_modules()['results'] ) entities.ContentViewPuppetModule( author=puppet_module['author'], name=puppet_module['name'], content_view=content_view, ).create() content_view.publish() content_view = content_view.read() # Promote the content view version. envs_amount = random.randint(3, 5) for _ in range(envs_amount): lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) # Everything's done. Check some content view attributes... content_view = content_view.read() self.assertEqual(len(content_view.version), 1) self.assertEqual(len(content_view.puppet_module), 1) # ...and some content view version attributes. cvv = content_view.version[0].read() self.assertEqual(len(cvv.environment), envs_amount + 1) self.assertEqual(len(cvv.puppet_module), 1)
def test_positive_promote_module_stream_filter(self): """Verify Module Stream, Errata Count after Promote, Publish for Content View with Module Stream Exclude Filter :id: 2f5d21b1-8cbc-4a77-b8a2-09aa466f56a3 :expectedresults: Content View should get published and promoted successfully with correct Module Stream count. :CaseLevel: Integration """ # Exclude module stream filter cv_filter = entities.ModuleStreamContentViewFilter( content_view=self.content_view, inclusion=False).create() module_streams = entities.ModuleStream().search( query={'search': 'name="{}"'.format('duck')}) entities.ContentViewFilterRule(content_view_filter=cv_filter, module_stream=module_streams).create() self.content_view.publish() content_view = self.content_view.read() content_view_version_info = content_view.version[0].read() assert len(content_view.repository) == 1 assert len(content_view.version) == 1 # the module stream and errata count based in filter after publish assert content_view_version_info.module_stream_count == 4 assert content_view_version_info.errata_counts['total'] == 3 # Promote Content View lce = entities.LifecycleEnvironment(organization=self.org).create() promote(content_view.version[0], lce.id) content_view = content_view.read() content_view_version_info = content_view.version[0].read() # assert the module stream and errata count based in filter after promote assert content_view_version_info.module_stream_count == 4 assert content_view_version_info.errata_counts['total'] == 3
def test_positive_rendering_after_env_removed(session): """Check if Dashboard UI rendered properly after lc environment for active organization is removed from the system :id: 81c52395-3476-4123-bc3b-49d6c658da9a :Steps: 1. Create an environment (e.g. Dev) 2. Create a content view and promote it to the environment 3. Remove the environment. 4. Visit the dashboard page and verify that it loads successfully. :expectedresults: Dashboard search box and necessary widgets are rendered before and after necessary environment is removed :BZ: 1361793 :CaseLevel: Integration """ org = entities.Organization().create() lc_env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() content_view.publish() promote(content_view.read().version[0], lc_env.id) with session: session.organization.select(org_name=org.name) values = session.dashboard.search('lifecycle_environment={}'.format( lc_env.name)) assert content_view.name in values['ContentViews'][ 'content_views'][0]['Content View'] entities.LifecycleEnvironment(id=lc_env.id).delete() values = session.dashboard.search('lifecycle_environment={}'.format( lc_env.name)) assert values['HostConfigurationStatus']['total_count'] == 0 assert content_view.name in values['ContentViews'][ 'content_views'][0]['Content View']
def test_positive_promote_multiple_with_docker_repo_composite( self, module_org): """Add Docker-type repository to content view and publish it. Then add that content view to composite one. Publish and promote that composite content view to the multiple available lifecycle-environments :id: 91ac0f4a-8974-47e2-a1d6-7d734aa4ad46 :expectedresults: Docker-type repository is promoted to content view found in the specific lifecycle-environments. """ repo = _create_repository( entities.Product(organization=module_org).create()) content_view = entities.ContentView(composite=False, organization=module_org).create() content_view.repository = [repo] content_view = content_view.update(['repository']) assert [repo.id] == [repo_.id for repo_ in content_view.repository] content_view.publish() cvv = content_view.read().version[0].read() comp_content_view = entities.ContentView( composite=True, organization=module_org).create() comp_content_view.component = [cvv] comp_content_view = comp_content_view.update(['component']) assert cvv.id == comp_content_view.component[0].id comp_content_view.publish() comp_cvv = comp_content_view.read().version[0] assert len(comp_cvv.read().environment) == 1 for i in range(1, randint(3, 6)): lce = entities.LifecycleEnvironment( organization=module_org).create() promote(comp_cvv, lce.id) assert len(comp_cvv.read().environment) == i + 1
def setup_content(module_org): with manifests.clone() as manifest: upload_manifest(module_org.id, manifest.content) rh_repo_id = enable_rhrepo_and_fetchid( basearch='x86_64', org_id=module_org.id, product=PRDS['rhel'], repo=REPOS['rhst7']['name'], reposet=REPOSET['rhst7'], releasever=None, ) rh_repo = entities.Repository(id=rh_repo_id).read() rh_repo.sync() custom_product = entities.Product(organization=module_org).create() custom_repo = entities.Repository(name=gen_string('alphanumeric').upper(), product=custom_product).create() custom_repo.sync() lce = entities.LifecycleEnvironment(organization=module_org).create() cv = entities.ContentView( organization=module_org, repository=[rh_repo_id, custom_repo.id], ).create() cv.publish() cvv = cv.read().version[0].read() promote(cvv, lce.id) ak = entities.ActivationKey(content_view=cv, organization=module_org, environment=lce, auto_attach=True).create() subscription = entities.Subscription(organization=module_org).search( query={'search': f'name="{DEFAULT_SUBSCRIPTION_NAME}"'})[0] ak.add_subscriptions(data={ 'quantity': 1, 'subscription_id': subscription.id }) return module_org, ak
def test_positive_check_dashboard( session, module_host_group, default_location, default_org, oscap_content_path, import_ansible_roles, ): """Create OpenScap Policy which is connected to the host. That policy dashboard should be rendered and correctly display information about the host :id: 3c1575cb-f290-4d99-bb86-61b9ca6a62eb :customerscenario: true :Steps: 1. Create new host group 2. Create new host using host group from step 1 3. Create an openscap content. 4. Create an openscap Policy using host group from step 1 :expectedresults: Policy dashboard rendered properly and has necessary data :BZ: 1424936 :CaseLevel: Integration """ name = gen_string('alpha') oscap_content_title = gen_string('alpha') lce = entities.LifecycleEnvironment(organization=default_org).create() content_view = entities.ContentView(organization=default_org).create() content_view.publish() content_view = content_view.read() promote(content_view.version[0], environment_id=lce.id) entities.Host( hostgroup=module_host_group, location=default_location, organization=default_org, content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': lce.id, }, ).create() entities.ScapContents( title=oscap_content_title, scap_file=oscap_content_path, organization=[default_org], location=[default_location], ).create() with session: session.organization.select(org_name=default_org.name) session.location.select(loc_name=default_location.name) session.oscappolicy.create( { 'deployment_options.deploy_by': 'ansible', 'policy_attributes.name': name, 'scap_content.scap_content_resource': oscap_content_title, 'scap_content.xccdf_profile': OSCAP_PROFILE['security7'], 'schedule.period': 'Weekly', 'schedule.period_selection.weekday': 'Friday', 'locations.resources.assigned': [default_location.name], 'organizations.resources.assigned': [default_org.name], 'host_group.resources.assigned': [module_host_group.name], } ) policy_details = session.oscappolicy.details(name) assert policy_details['HostsBreakdownStatus']['total_count'] == 1
def test_positive_end_to_end(self): """Perform end to end smoke tests using RH and custom repos. 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Clone and upload manifest 3. Create a new lifecycle environment 4. Create a custom product 5. Create a custom YUM repository 6. Create a custom PUPPET repository 7. Enable a Red Hat repository 8. Synchronize the three repositories 9. Create a new content view 10. Associate the YUM and Red Hat repositories to new content view 11. Add a PUPPET module to new content view 12. Publish content view 13. Promote content view to the lifecycle environment 14. Create a new activation key 15. Add the products to the activation key 16. Create a new libvirt compute resource 17. Create a new subnet 18. Create a new domain 19. Create a new hostgroup and associate previous entities to it 20. Provision a client :id: b2f73740-d3ce-4e6e-abc7-b23e5562bac1 :expectedresults: All tests should succeed and Content should be successfully fetched by client. """ # step 1: Create a new user with admin permissions login = gen_string('alphanumeric') password = gen_string('alphanumeric') entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Clone and upload manifest if self.fake_manifest_is_set: with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) # step 2.3: Create a new lifecycle environment le1 = entities.LifecycleEnvironment(server_config, organization=org).create() # step 2.4: Create a custom product prod = entities.Product(server_config, organization=org).create() repositories = [] # step 2.5: Create custom YUM repository repo1 = entities.Repository(server_config, product=prod, content_type='yum', url=CUSTOM_RPM_REPO).create() repositories.append(repo1) # step 2.6: Create custom PUPPET repository repo2 = entities.Repository(server_config, product=prod, content_type='puppet', url=FAKE_0_PUPPET_REPO).create() repositories.append(repo2) # step 2.7: Enable a Red Hat repository if self.fake_manifest_is_set: repo3 = entities.Repository(id=enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhva6']['name'], reposet=REPOSET['rhva6'], releasever='6Server', )) repositories.append(repo3) # step 2.8: Synchronize the three repositories for repo in repositories: repo.sync() # step 2.9: Create content view content_view = entities.ContentView(server_config, organization=org).create() # step 2.10: Associate the YUM and Red Hat repositories to new content # view repositories.remove(repo2) content_view.repository = repositories content_view = content_view.update(['repository']) # step 2.11: Add a PUPPET module to new content view puppet_mods = content_view.available_puppet_modules() self.assertGreater(len(puppet_mods['results']), 0) puppet_module = random.choice(puppet_mods['results']) puppet = entities.ContentViewPuppetModule( author=puppet_module['author'], content_view=content_view, name=puppet_module['name']).create() self.assertEqual(puppet.name, puppet_module['name']) # step 2.12: Publish content view content_view.publish() # step 2.13: Promote content view to the lifecycle environment content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = content_view.version[0].read() self.assertEqual(len(cv_version.environment), 1) promote(cv_version, le1.id) # check that content view exists in lifecycle content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cv_version = cv_version.read() # step 2.14: Create a new activation key activation_key_name = gen_string('alpha') activation_key = entities.ActivationKey( name=activation_key_name, environment=le1, organization=org, content_view=content_view).create() # step 2.15: Add the products to the activation key for sub in entities.Subscription(organization=org).search(): if sub.name == DEFAULT_SUBSCRIPTION_NAME: activation_key.add_subscriptions(data={ 'quantity': 1, 'subscription_id': sub.id }) break # step 2.15.1: Enable product content if self.fake_manifest_is_set: activation_key.content_override( data={ 'content_overrides': [{ 'content_label': AK_CONTENT_LABEL, 'value': '1' }] }) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.Host( content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': le1.id, }, organization=org, ).create() # check that content view matches what we passed self.assertEqual( content_host.content_facet_attributes['content_view_id'], content_view.id) # check that lifecycle environment matches self.assertEqual( content_host.content_facet_attributes['lifecycle_environment_id'], le1.id) # step 2.16: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url='qemu+ssh://root@{0}/system'.format( settings.compute_resources.libvirt_hostname), ).create() # step 2.17: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.18: Create a new domain domain = entities.Domain(server_config).create() # step 2.19: Create a new hostgroup and associate previous entities to # it entities.HostGroup(server_config, domain=domain, subnet=subnet).create() # step 2.20: Provision a client self.client_provisioning(activation_key_name, org.label)
def test_positive_get_applicable_for_host(self): """Get applicable errata ids for a host :id: 51d44d51-eb3f-4ee4-a1df-869629d427ac :Setup: 1. Errata synced on satellite server. 2. Some Content hosts present. :Steps: GET /api/v2/hosts/:id/errata :expectedresults: The available errata is retrieved. :CaseLevel: System """ org = entities.Organization().create() env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() activation_key = entities.ActivationKey(environment=env, organization=org).create() setup_org_for_a_rh_repo( { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhst6'], 'repository': REPOS['rhst6']['name'], 'organization-id': org.id, 'content-view-id': content_view.id, 'lifecycle-environment-id': env.id, 'activationkey-id': activation_key.id, }, force_manifest_upload=True, ) setup_org_for_a_custom_repo({ 'url': CUSTOM_REPO_URL, 'organization-id': org.id, 'content-view-id': content_view.id, 'lifecycle-environment-id': env.id, 'activationkey-id': activation_key.id, }) repo_id = enable_rhrepo_and_fetchid( basearch=DEFAULT_ARCHITECTURE, org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhva6']['name'], reposet=REPOSET['rhva6'], releasever=DEFAULT_RELEASE_VERSION, ) repo = entities.Repository(id=repo_id) self.assertEqual(repo.sync()['result'], 'success') content_view = content_view.read() content_view.repository.append(repo) content_view = content_view.update(['repository']) content_view.publish() versions = sorted(content_view.read().version, key=lambda ver: ver.id) cvv = versions[-1].read() promote(cvv, env.id) with VirtualMachine(distro=DISTRO_RHEL6) as client: client.install_katello_ca() client.register_contenthost(org.label, activation_key.name) self.assertTrue(client.subscribed) client.enable_repo(REPOS['rhst6']['id']) client.enable_repo(REPOS['rhva6']['id']) client.install_katello_agent() host = (entities.Host().search( query={'search': 'name={0}'.format(client.hostname)}) [0].read()) erratum = self._fetch_available_errata(host, 0) self.assertEqual(len(erratum), 0) client.run('yum install -y {0}'.format(FAKE_1_CUSTOM_PACKAGE)) erratum = self._fetch_available_errata(host, 1) self.assertEqual(len(erratum), 1) self.assertIn(CUSTOM_REPO_ERRATA_ID, [errata['errata_id'] for errata in erratum]) client.run('yum install -y {0}'.format(REAL_0_RH_PACKAGE)) erratum = self._fetch_available_errata(host, 3) self.assertEqual(len(erratum), 3) self.assertTrue({REAL_1_ERRATA_ID, REAL_2_ERRATA_ID}.issubset( {errata['errata_id'] for errata in erratum}))
def test_positive_get_count_for_host(self): """Available errata count when retrieving Host :id: 2f35933f-8026-414e-8f75-7f4ec048faae :Setup: 1. Errata synced on satellite server. 2. Some Content hosts present. :Steps: GET /api/v2/hosts :expectedresults: The available errata count is retrieved. :CaseLevel: System """ org = entities.Organization().create() env = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() activation_key = entities.ActivationKey(environment=env, organization=org).create() setup_org_for_a_rh_repo( { 'product': PRDS['rhel'], 'repository-set': REPOSET['rhst6'], 'repository': REPOS['rhst6']['name'], 'organization-id': org.id, 'content-view-id': content_view.id, 'lifecycle-environment-id': env.id, 'activationkey-id': activation_key.id, }, force_manifest_upload=True, ) setup_org_for_a_custom_repo({ 'url': CUSTOM_REPO_URL, 'organization-id': org.id, 'content-view-id': content_view.id, 'lifecycle-environment-id': env.id, 'activationkey-id': activation_key.id, }) repo_id = enable_rhrepo_and_fetchid( basearch=DEFAULT_ARCHITECTURE, org_id=org.id, product=PRDS['rhel'], repo=REPOS['rhva6']['name'], reposet=REPOSET['rhva6'], releasever=DEFAULT_RELEASE_VERSION, ) repo = entities.Repository(id=repo_id) self.assertEqual(repo.sync()['result'], 'success') content_view = content_view.read() content_view.repository.append(repo) content_view = content_view.update(['repository']) content_view.publish() versions = sorted(content_view.read().version, key=lambda ver: ver.id) cvv = versions[-1].read() promote(cvv, env.id) with VirtualMachine(distro=DISTRO_RHEL6) as client: client.install_katello_ca() client.register_contenthost(org.label, activation_key.name) self.assertTrue(client.subscribed) client.enable_repo(REPOS['rhst6']['id']) client.enable_repo(REPOS['rhva6']['id']) client.install_katello_agent() host = (entities.Host().search( query={'search': 'name={0}'.format(client.hostname)}) [0].read()) for errata in ('security', 'bugfix', 'enhancement'): self._validate_errata_counts(host, errata, 0) client.run('yum install -y {0}'.format(FAKE_1_CUSTOM_PACKAGE)) self._validate_errata_counts(host, 'security', 1) client.run('yum install -y {0}'.format(REAL_0_RH_PACKAGE)) for errata in ('bugfix', 'enhancement'): self._validate_errata_counts(host, errata, 1)
def test_positive_filtered_errata_status_installable_param( session, errata_status_installable): """Filter errata for specific content view and verify that host that was registered using that content view has different states in correspondence to filtered errata and `errata status installable` settings flag value :id: ed94cf34-b8b9-4411-8edc-5e210ea6af4f :Steps: 1. Prepare setup: Create Lifecycle Environment, Content View, Activation Key and all necessary repos 2. Register Content Host using created data 3. Create necessary Content View Filter and Rule for repository errata 4. Publish and Promote Content View to a new version. 5. Go to created Host page and check its properties 6. Change 'errata status installable' flag in the settings and check host properties once more :expectedresults: Check that 'errata status installable' flag works as intended :BZ: 1368254 :CaseLevel: System """ org = entities.Organization().create() lce = entities.LifecycleEnvironment(organization=org).create() repos_collection = RepositoryCollection( distro=DISTRO_RHEL7, repositories=[ SatelliteToolsRepository(), # As Satellite Tools may be added as custom repo and to have a "Fully entitled" host, # force the host to consume an RH product with adding a cdn repo. RHELAnsibleEngineRepository(cdn=True), YumRepository(url=CUSTOM_REPO_URL), ], ) repos_collection.setup_content(org.id, lce.id, upload_manifest=True) with VirtualMachine(distro=repos_collection.distro) as client: repos_collection.setup_virtual_machine(client) assert _install_client_package(client, FAKE_1_CUSTOM_PACKAGE, errata_applicability=True) # Adding content view filter and content view filter rule to exclude errata for the # installed package. content_view = entities.ContentView( id=repos_collection.setup_content_data['content_view'] ['id']).read() cv_filter = entities.ErratumContentViewFilter( content_view=content_view, inclusion=False).create() errata = entities.Errata( content_view_version=content_view.version[-1]).search(query=dict( search=f'errata_id="{CUSTOM_REPO_ERRATA_ID}"'))[0] entities.ContentViewFilterRule(content_view_filter=cv_filter, errata=errata).create() content_view.publish() content_view = content_view.read() content_view_version = content_view.version[-1] promote(content_view_version, lce.id) with session: session.organization.select(org_name=org.name) _set_setting_value(errata_status_installable, True) expected_values = { 'Status': 'OK', 'Errata': 'All errata applied', 'Subscription': 'Fully entitled', } host_details_values = session.host.get_details(client.hostname) actual_values = { key: value for key, value in host_details_values['properties'] ['properties_table'].items() if key in expected_values } for key in actual_values: assert expected_values[key] in actual_values[ key], 'Expected text not found' _set_setting_value(errata_status_installable, False) expected_values = { 'Status': 'Error', 'Errata': 'Security errata applicable', 'Subscription': 'Fully entitled', } # navigate to host main page by making a search, to refresh the host details page session.host.search(client.hostname) host_details_values = session.host.get_details(client.hostname) actual_values = { key: value for key, value in host_details_values['properties'] ['properties_table'].items() if key in expected_values } for key in actual_values: assert expected_values[key] in actual_values[ key], 'Expected text not found'
def test_positive_sync_puppet_module_with_versions(self): """Ensure it's possible to sync multiple versions of the same puppet module to the capsule :id: 83a0ddd6-8a6a-43a0-b169-094a2556dd28 :customerscenario: true :BZ: 1365952, 1655243 :Steps: 1. Register a capsule 2. Associate LCE with the capsule 3. Sync a puppet module with multiple versions 4. Publish a CV with one version of puppet module and promote it to capsule's LCE 5. Wait for capsule synchronization to finish 6. Publish another CV with different version of puppet module and promote it to capsule's LCE 7. Wait for capsule synchronization to finish once more :expectedresults: Capsule was successfully synchronized, new version of puppet module is present on capsule :CaseLevel: System :CaseImportance: Medium """ module_name = 'versioned' module_versions = ['2.2.2', '3.3.3'] org = entities.Organization().create() lce = entities.LifecycleEnvironment(organization=org).create() content_view = entities.ContentView(organization=org).create() prod = entities.Product(organization=org).create() puppet_repository = entities.Repository( content_type=REPO_TYPE['puppet'], product=prod, url=CUSTOM_PUPPET_REPO, ).create() capsule = entities.Capsule(id=self.capsule_id).read() capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) puppet_repository.sync() puppet_module_old = entities.PuppetModule().search( query={ 'search': 'name={} and version={}'.format(module_name, module_versions[0]) })[0] # Add puppet module to the CV entities.ContentViewPuppetModule( content_view=content_view, id=puppet_module_old.id, ).create() content_view = content_view.read() self.assertGreater(len(content_view.puppet_module), 0) # Publish and promote CVV content_view.publish() content_view = content_view.read() self.assertEqual(len(content_view.version), 1) cvv = content_view.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Wait till capsule sync finishes sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() sync_status = capsule.content_get_sync() last_sync_time = sync_status['last_sync_time'] # Unassign old puppet module version from CV entities.ContentViewPuppetModule( content_view=content_view, id=content_view.puppet_module[0].id, ).delete() # Assign new puppet module version puppet_module_new = entities.PuppetModule().search( query={ 'search': 'name={} and version={}'.format(module_name, module_versions[1]) })[0] entities.ContentViewPuppetModule( content_view=content_view, id=puppet_module_new.id, ).create() self.assertGreater(len(content_view.puppet_module), 0) # Publish and promote CVV content_view.publish() content_view = content_view.read() self.assertEqual(len(content_view.version), 2) cvv = content_view.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Wait till capsule sync finishes sync_status = capsule.content_get_sync() if sync_status['active_sync_tasks']: for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() else: self.assertNotEqual(sync_status['last_sync_time'], last_sync_time) stored_modules = get_repo_files(PULP_PUBLISHED_PUPPET_REPOS_PATH, 'gz', self.capsule_ip) with self.assertNotRaises(StopIteration): next( filename for filename in stored_modules if '{}-{}'.format(module_name, module_versions[1]) in filename)
def test_positive_end_to_end(self, fake_manifest_is_set, default_sat, rhel7_contenthost): """Perform end to end smoke tests using RH and custom repos. 1. Create a new user with admin permissions 2. Using the new user from above 1. Create a new organization 2. Clone and upload manifest 3. Create a new lifecycle environment 4. Create a custom product 5. Create a custom YUM repository 6. Enable a Red Hat repository 7. Synchronize these two repositories 8. Create a new content view 9. Associate the YUM and Red Hat repositories to new content view 10. Publish content view 11. Promote content view to the lifecycle environment 12. Create a new activation key 13. Add the products to the activation key 14. Create a new libvirt compute resource 15. Create a new subnet 16. Create a new domain 17. Create a new hostgroup and associate previous entities to it 18. Provision a client ** NOT CURRENTLY PROVISIONING :id: b2f73740-d3ce-4e6e-abc7-b23e5562bac1 :expectedresults: All tests should succeed and Content should be successfully fetched by client. :parametrized: yes """ # step 1: Create a new user with admin permissions login = gen_string('alphanumeric') password = gen_string('alphanumeric') entities.User(admin=True, login=login, password=password).create() # step 2.1: Create a new organization server_config = get_nailgun_config() server_config.auth = (login, password) org = entities.Organization(server_config).create() # step 2.2: Clone and upload manifest if fake_manifest_is_set: with manifests.clone() as manifest: upload_manifest(org.id, manifest.content) # step 2.3: Create a new lifecycle environment le1 = entities.LifecycleEnvironment(server_config, organization=org).create() # step 2.4: Create a custom product prod = entities.Product(server_config, organization=org).create() repositories = [] # step 2.5: Create custom YUM repository custom_repo = entities.Repository(server_config, product=prod, content_type='yum', url=CUSTOM_RPM_REPO).create() repositories.append(custom_repo) # step 2.6: Enable a Red Hat repository if fake_manifest_is_set: rhel_repo = entities.Repository(id=enable_rhrepo_and_fetchid( basearch='x86_64', org_id=org.id, product=constants.PRDS['rhel'], repo=constants.REPOS['rhst7']['name'], reposet=constants.REPOSET['rhst7'], )) repositories.append(rhel_repo) # step 2.7: Synchronize these two repositories for repo in repositories: repo.sync() # step 2.8: Create content view content_view = entities.ContentView(server_config, organization=org).create() # step 2.9: Associate the YUM and Red Hat repositories to new content view content_view.repository = repositories content_view = content_view.update(['repository']) # step 2.10: Publish content view content_view.publish() # step 2.11: Promote content view to the lifecycle environment content_view = content_view.read() assert len(content_view.version) == 1 cv_version = content_view.version[0].read() assert len(cv_version.environment) == 1 promote(cv_version, le1.id) # check that content view exists in lifecycle content_view = content_view.read() assert len(content_view.version) == 1 cv_version = cv_version.read() # step 2.12: Create a new activation key activation_key_name = gen_string('alpha') activation_key = entities.ActivationKey( name=activation_key_name, environment=le1, organization=org, content_view=content_view).create() # step 2.13: Add the products to the activation key for sub in entities.Subscription(organization=org).search(): if sub.name == constants.DEFAULT_SUBSCRIPTION_NAME: activation_key.add_subscriptions(data={ 'quantity': 1, 'subscription_id': sub.id }) break # step 2.13.1: Enable product content if fake_manifest_is_set: activation_key.content_override( data={ 'content_overrides': [{ 'content_label': constants.REPOS['rhst7']['id'], 'value': '1' }] }) # BONUS: Create a content host and associate it with promoted # content view and last lifecycle where it exists content_host = entities.Host( content_facet_attributes={ 'content_view_id': content_view.id, 'lifecycle_environment_id': le1.id, }, organization=org, ).create() # check that content view matches what we passed assert content_host.content_facet_attributes[ 'content_view_id'] == content_view.id # check that lifecycle environment matches assert content_host.content_facet_attributes[ 'lifecycle_environment_id'] == le1.id # step 2.14: Create a new libvirt compute resource entities.LibvirtComputeResource( server_config, url=f'qemu+ssh://root@{settings.libvirt.libvirt_hostname}/system', ).create() # step 2.15: Create a new subnet subnet = entities.Subnet(server_config).create() # step 2.16: Create a new domain domain = entities.Domain(server_config).create() # step 2.17: Create a new hostgroup and associate previous entities to it entities.HostGroup(server_config, domain=domain, subnet=subnet).create() # step 2.18: Provision a client # TODO this isn't provisioning through satellite as intended # Note it wasn't well before the change that added this todo rhel7_contenthost.install_katello_ca(default_sat) # Register client with foreman server using act keys rhel7_contenthost.register_contenthost(org.label, activation_key_name) assert rhel7_contenthost.subscribed # Install rpm on client package_name = 'katello-agent' result = rhel7_contenthost.execute(f'yum install -y {package_name}') assert result.status == 0 # Verify that the package is installed by querying it result = rhel7_contenthost.run(f'rpm -q {package_name}') assert result.status == 0
def test_positive_checksum_sync(self): """Synchronize repository to capsule, update repository's checksum type, trigger capsule sync and make sure checksum type was updated on capsule :id: eb07bdf3-6cd8-4a2f-919b-8dfc84e16115 :customerscenario: true :BZ: 1288656, 1664288, 1732066 :expectedresults: checksum type is updated in repodata of corresponding repository on capsule :CaseLevel: System :CaseImportance: Critical """ repomd_path = 'repodata/repomd.xml' # Create organization, product, lce and repository with sha256 checksum # type org = entities.Organization(smart_proxy=[self.capsule_id]).create() product = entities.Product(organization=org).create() repo = entities.Repository(product=product, checksum_type='sha256', download_policy='immediate').create() lce = entities.LifecycleEnvironment(organization=org).create() # Associate the lifecycle environment with the capsule capsule = entities.Capsule(id=self.capsule_id).read() capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Sync, publish and promote a repo cv = entities.ContentView( organization=org, repository=[repo], ).create() repo.sync() repo = repo.read() cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) cvv = cv.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Wait till capsule sync finishes sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() sync_status = capsule.content_get_sync() last_sync_time = sync_status['last_sync_time'] # Verify repodata's checksum type is sha256, not sha1 on capsule lce_repo_path = form_repo_path( org=org.label, lce=lce.label, cv=cv.label, prod=product.label, repo=repo.label, ) result = ssh.command('grep -o \'checksum type="sha1"\' {}/{}'.format( lce_repo_path, repomd_path), hostname=self.capsule_ip) self.assertNotEqual(result.return_code, 0) self.assertEqual(len(result.stdout), 0) result = ssh.command('grep -o \'checksum type="sha256"\' {}/{}'.format( lce_repo_path, repomd_path), hostname=self.capsule_ip) self.assertEqual(result.return_code, 0) self.assertGreater(len(result.stdout), 0) # Update repo's checksum type to sha1 repo.checksum_type = 'sha1' repo = repo.update(['checksum_type']) # Sync, publish and promote repo repo.sync() cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 2) cv.version.sort(key=lambda version: version.id) cvv = cv.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Wait till capsule sync finishes sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time'] != last_sync_time) for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() # Verify repodata's checksum type has updated to sha1 on capsule result = ssh.command('grep -o \'checksum type="sha256"\' {}/{}'.format( lce_repo_path, repomd_path), hostname=self.capsule_ip) self.assertNotEqual(result.return_code, 0) self.assertEqual(len(result.stdout), 0) result = ssh.command('grep -o \'checksum type="sha1"\' {}/{}'.format( lce_repo_path, repomd_path), hostname=self.capsule_ip) self.assertEqual(result.return_code, 0) self.assertGreater(len(result.stdout), 0)
def test_positive_update_with_immediate_sync(self): """Create a repository with on_demand download policy, associate it with capsule, sync repo, update download policy to immediate, sync once more. :id: 511b531d-1fbe-4d64-ae31-0f9eb6625e7f :customerscenario: true :BZ: 1315752 :expectedresults: content was successfully synchronized - capsule filesystem contains valid links to packages :CaseLevel: System """ repo_url = FAKE_1_YUM_REPO packages_count = FAKE_1_YUM_REPOS_COUNT # Create organization, product, repository in satellite, and lifecycle # environment org = entities.Organization().create() prod = entities.Product(organization=org).create() repo = entities.Repository( download_policy='on_demand', mirror_on_sync=True, product=prod, url=repo_url, ).create() lce = entities.LifecycleEnvironment(organization=org).create() # Update capsule's download policy to on_demand to match repository's # policy self.update_capsule_download_policy(self.capsule_id, 'on_demand') # Associate the lifecycle environment with the capsule capsule = entities.Capsule(id=self.capsule_id).read() capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Create a content view with the repository cv = entities.ContentView( organization=org, repository=[repo], ).create() # Sync repository repo.sync() repo = repo.read() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) cvv = cv.version[-1].read() # Promote content view to lifecycle environment promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() # Update download policy to 'immediate' repo.download_policy = 'immediate' repo = repo.update(['download_policy']) self.assertEqual(repo.download_policy, 'immediate') # Update capsule's download policy as well self.update_capsule_download_policy(self.capsule_id, 'immediate') # Make sure to revert capsule's download policy after the test as the # capsule is shared among other tests self.addCleanup(self.update_capsule_download_policy, self.capsule_id, 'on_demand') # Sync repository once again repo.sync() repo = repo.read() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 2) cv.version.sort(key=lambda version: version.id) cvv = cv.version[-1].read() # Promote content view to lifecycle environment promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Check whether the symlinks for all the packages were created on # satellite cvv_repo_path = form_repo_path( org=org.label, cv=cv.label, cvv=cvv.version, prod=prod.label, repo=repo.label, ) result = ssh.command('find {}/ -type l'.format(cvv_repo_path)) self.assertEqual(result.return_code, 0) links = set(link for link in result.stdout if link) self.assertEqual(len(links), packages_count) # Ensure there're no broken symlinks (pointing to nonexistent files) on # satellite result = ssh.command( 'find {}/ -type l ! -exec test -e {{}} \\; -print'.format( cvv_repo_path)) self.assertEqual(result.return_code, 0) broken_links = set(link for link in result.stdout if link) self.assertEqual(len(broken_links), 0) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() lce_repo_path = form_repo_path( org=org.label, lce=lce.label, cv=cv.label, prod=prod.label, repo=repo.label, ) # Check whether the symlinks for all the packages were created on # capsule result = ssh.command('find {}/ -type l'.format(lce_repo_path), hostname=self.capsule_ip) self.assertEqual(result.return_code, 0) links = set(link for link in result.stdout if link) self.assertEqual(len(links), packages_count) # Ensure there're no broken symlinks (pointing to nonexistent files) on # capsule result = ssh.command( 'find {}/ -type l ! -exec test -e {{}} \\; -print'.format( lce_repo_path), hostname=self.capsule_ip) self.assertEqual(result.return_code, 0) broken_links = set(link for link in result.stdout if link) self.assertEqual(len(broken_links), 0)
def test_positive_mirror_on_sync(self): """Create 2 repositories with 'on_demand' download policy and mirror on sync option, associate them with capsule, sync first repo, move package from first repo to second one, sync it, attempt to install package on some host. :id: 39149642-1e7e-4ef8-8762-bec295913014 :BZ: 1426408 :expectedresults: host, subscribed to second repo only, can successfully install package :CaseLevel: System """ repo1_name = gen_string('alphanumeric') repo2_name = gen_string('alphanumeric') # Create and publish first custom repository with 2 packages in it repo1_url = create_repo( repo1_name, FAKE_1_YUM_REPO, FAKE_1_YUM_REPO_RPMS[1:3], ) # Create and publish second repo with no packages in it repo2_url = create_repo(repo2_name) # Create organization, product, repository in satellite, and lifecycle # environment org = entities.Organization().create() prod1 = entities.Product(organization=org).create() repo1 = entities.Repository( download_policy='on_demand', mirror_on_sync=True, product=prod1, url=repo1_url, ).create() prod2 = entities.Product(organization=org).create() repo2 = entities.Repository( download_policy='on_demand', mirror_on_sync=True, product=prod2, url=repo2_url, ).create() lce1 = entities.LifecycleEnvironment(organization=org).create() lce2 = entities.LifecycleEnvironment(organization=org).create() # Associate the lifecycle environments with the capsule capsule = entities.Capsule(id=self.capsule_id).read() for lce_id in (lce1.id, lce2.id): capsule.content_add_lifecycle_environment(data={ 'environment_id': lce_id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 2) self.assertTrue({lce1.id, lce2.id}.issubset( [capsule_lce['id'] for capsule_lce in result['results']]), ) # Create content views with the repositories cv1 = entities.ContentView( organization=org, repository=[repo1], ).create() cv2 = entities.ContentView( organization=org, repository=[repo2], ).create() # Sync first repository repo1.sync() repo1 = repo1.read() # Publish new version of the content view cv1.publish() cv1 = cv1.read() self.assertEqual(len(cv1.version), 1) cvv1 = cv1.version[-1].read() # Promote content view to lifecycle environment promote(cvv1, lce1.id) cvv1 = cvv1.read() self.assertEqual(len(cvv1.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() # Move one package from the first repo to second one ssh.command('mv {} {}'.format( os.path.join( PULP_PUBLISHED_YUM_REPOS_PATH, repo1_name, FAKE_1_YUM_REPO_RPMS[2], ), os.path.join( PULP_PUBLISHED_YUM_REPOS_PATH, repo2_name, FAKE_1_YUM_REPO_RPMS[2], ), )) # Update repositories (re-trigger 'createrepo' command) create_repo(repo1_name) create_repo(repo2_name) # Synchronize first repository repo1.sync() cv1.publish() cv1 = cv1.read() self.assertEqual(len(cv1.version), 2) cv1.version.sort(key=lambda version: version.id) cvv1 = cv1.version[-1].read() # Promote content view to lifecycle environment promote(cvv1, lce1.id) cvv1 = cvv1.read() self.assertEqual(len(cvv1.environment), 2) # Synchronize second repository repo2.sync() repo2 = repo2.read() self.assertEqual(repo2.content_counts['package'], 1) cv2.publish() cv2 = cv2.read() self.assertEqual(len(cv2.version), 1) cvv2 = cv2.version[-1].read() # Promote content view to lifecycle environment promote(cvv2, lce2.id) cvv2 = cvv2.read() self.assertEqual(len(cvv2.environment), 2) # Create activation key, add subscription to second repo only activation_key = entities.ActivationKey( content_view=cv2, environment=lce2, organization=org, ).create() subscription = entities.Subscription(organization=org).search( query={'search': 'name={}'.format(prod2.name)})[0] activation_key.add_subscriptions( data={'subscription_id': subscription.id}) # Subscribe a host with activation key with VirtualMachine(distro=DISTRO_RHEL7) as client: client.install_katello_ca() client.register_contenthost( org.label, activation_key.name, ) # Install the package package_name = FAKE_1_YUM_REPO_RPMS[2].rstrip('.rpm') result = client.run('yum install -y {}'.format(package_name)) self.assertEqual(result.return_code, 0) # Ensure package installed result = client.run('rpm -qa | grep {}'.format(package_name)) self.assertEqual(result.return_code, 0) self.assertIn(package_name, result.stdout[0])
def test_positive_on_demand_sync(self): """Create a repository with 'on_demand' sync, add it to lifecycle environment with a capsule, sync repository, examine existing packages on capsule, download any package, examine packages once more :id: ba470269-a7ad-4181-bc7c-8e17a177ca20 :expectedresults: 1. After initial syncing only symlinks are present on both satellite and capsule, no real packages were fetched. 2. All the symlinks are pointing to non-existent files. 3. Attempt to download package is successful 4. Downloaded package checksum matches checksum of the source package :CaseLevel: System """ repo_url = FAKE_3_YUM_REPO packages_count = FAKE_3_YUM_REPOS_COUNT package = FAKE_1_YUM_REPO_RPMS[0] # Create organization, product, repository in satellite, and lifecycle # environment org = entities.Organization().create() prod = entities.Product(organization=org).create() repo = entities.Repository( download_policy='on_demand', mirror_on_sync=True, product=prod, url=repo_url, ).create() lce = entities.LifecycleEnvironment(organization=org).create() # Associate the lifecycle environment with the capsule capsule = entities.Capsule(id=self.capsule_id).read() capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Create a content view with the repository cv = entities.ContentView( organization=org, repository=[repo], ).create() # Sync repository repo.sync() repo = repo.read() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) cvv = cv.version[-1].read() # Promote content view to lifecycle environment promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Check whether the symlinks for all the packages were created on # satellite cvv_repo_path = form_repo_path( org=org.label, cv=cv.label, cvv=cvv.version, prod=prod.label, repo=repo.label, ) result = ssh.command('find {}/ -type l'.format(cvv_repo_path)) self.assertEqual(result.return_code, 0) links = set(link for link in result.stdout if link) self.assertEqual(len(links), packages_count) # Ensure all the symlinks on satellite are broken (pointing to # nonexistent files) result = ssh.command( 'find {}/ -type l ! -exec test -e {{}} \\; -print'.format( cvv_repo_path)) self.assertEqual(result.return_code, 0) broken_links = set(link for link in result.stdout if link) self.assertEqual(len(broken_links), packages_count) self.assertEqual(broken_links, links) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() lce_repo_path = form_repo_path( org=org.label, lce=lce.label, cv=cv.label, prod=prod.label, repo=repo.label, ) # Check whether the symlinks for all the packages were created on # capsule result = ssh.command( 'find {}/ -type l'.format(lce_repo_path), hostname=self.capsule_ip, ) self.assertEqual(result.return_code, 0) links = set(link for link in result.stdout if link) self.assertEqual(len(links), packages_count) # Ensure all the symlinks on capsule are broken (pointing to # nonexistent files) result = ssh.command( 'find {}/ -type l ! -exec test -e {{}} \\; -print'.format( lce_repo_path), hostname=self.capsule_ip, ) self.assertEqual(result.return_code, 0) broken_links = set(link for link in result.stdout if link) self.assertEqual(len(broken_links), packages_count) self.assertEqual(broken_links, links) # Download package from satellite and get its md5 checksum published_repo_url = 'http://{}{}/pulp/{}/'.format( settings.server.hostname, ':{}'.format(settings.server.port) if settings.server.port else '', lce_repo_path.split('http/')[1]) package_md5 = md5_by_url('{}{}'.format(repo_url, package)) # Get md5 checksum of source package published_package_md5 = md5_by_url('{}{}'.format( published_repo_url, package)) # Assert checksums are matching self.assertEqual(package_md5, published_package_md5)
def test_positive_capsule_sync(self): """Create repository, add it to lifecycle environment, assign lifecycle environment with a capsule, sync repository, sync it once again, update repository (add 1 new package), sync repository once again. :id: 35513099-c918-4a8e-90d0-fd4c87ad2f82 :customerscenario: true :BZ: 1394354, 1439691 :expectedresults: 1. Repository sync triggers capsule sync 2. After syncing capsule contains same repo content as satellite 3. Syncing repository which has no changes for a second time does not trigger any new publish task 4. Repository revision on capsule remains exactly the same after second repo sync with no changes 5. Syncing repository which was updated will update the content on capsule :CaseLevel: System """ repo_name = gen_string('alphanumeric') # Create and publish custom repository with 2 packages in it repo_url = create_repo( repo_name, FAKE_1_YUM_REPO, FAKE_1_YUM_REPO_RPMS[0:2], ) # Create organization, product, repository in satellite, and lifecycle # environment org = entities.Organization(smart_proxy=[self.capsule_id]).create() product = entities.Product(organization=org).create() repo = entities.Repository( product=product, url=repo_url, ).create() lce = entities.LifecycleEnvironment(organization=org).create() # Associate the lifecycle environment with the capsule capsule = entities.Capsule(id=self.capsule_id).read() capsule.content_add_lifecycle_environment(data={ 'environment_id': lce.id, }) result = capsule.content_lifecycle_environments() self.assertGreaterEqual(len(result['results']), 1) self.assertIn(lce.id, [capsule_lce['id'] for capsule_lce in result['results']]) # Create a content view with the repository cv = entities.ContentView( organization=org, repository=[repo], ).create() # Sync repository repo.sync() repo = repo.read() # Publish new version of the content view cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 1) cvv = cv.version[-1].read() # Promote content view to lifecycle environment promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time']) # Assert that the content of the published content view in # lifecycle environment is exactly the same as content of # repository lce_repo_path = form_repo_path( org=org.label, lce=lce.label, cv=cv.label, prod=product.label, repo=repo.label, ) cvv_repo_path = form_repo_path( org=org.label, cv=cv.label, cvv=cvv.version, prod=product.label, repo=repo.label, ) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() sync_status = capsule.content_get_sync() last_sync_time = sync_status['last_sync_time'] # If BZ1439691 is open, need to sync repo once more, as repodata # will change on second attempt even with no changes in repo if is_open('BZ:1439691'): repo.sync() repo = repo.read() cv.publish() cv = cv.read() self.assertEqual(len(cv.version), 2) cv.version.sort(key=lambda version: version.id) cvv = cv.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time'] != last_sync_time) for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() sync_status = capsule.content_get_sync() last_sync_time = sync_status['last_sync_time'] # Assert that the content published on the capsule is exactly the # same as in repository on satellite lce_revision_capsule = get_repomd_revision(lce_repo_path, hostname=self.capsule_ip) self.assertEqual( get_repo_files(lce_repo_path, hostname=self.capsule_ip), get_repo_files(cvv_repo_path)) # Sync repository for a second time result = repo.sync() # Assert that the task summary contains a message that says the # publish was skipped because content had not changed self.assertEqual(result['result'], 'success') self.assertTrue(result['output']['post_sync_skipped']) self.assertEqual(result['humanized']['output'], 'No new packages.') # Publish a new version of content view cv.publish() cv = cv.read() cv.version.sort(key=lambda version: version.id) cvv = cv.version[-1].read() # Promote new content view version to lifecycle environment promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Wait till capsule sync finishes sync_status = capsule.content_get_sync() tasks = [] if not sync_status['active_sync_tasks']: self.assertNotEqual(sync_status['last_sync_time'], last_sync_time) else: for task in sync_status['active_sync_tasks']: tasks.append(entities.ForemanTask(id=task['id'])) tasks[-1].poll() # Assert that the value of repomd revision of repository in # lifecycle environment on the capsule has not changed new_lce_revision_capsule = get_repomd_revision( lce_repo_path, hostname=self.capsule_ip) self.assertEqual(lce_revision_capsule, new_lce_revision_capsule) # Update a repository with 1 new rpm create_repo( repo_name, FAKE_1_YUM_REPO, FAKE_1_YUM_REPO_RPMS[-1:], ) # Sync, publish and promote the repository repo.sync() repo = repo.read() cv.publish() cv = cv.read() cv.version.sort(key=lambda version: version.id) cvv = cv.version[-1].read() promote(cvv, lce.id) cvv = cvv.read() self.assertEqual(len(cvv.environment), 2) # Assert that a task to sync lifecycle environment to the capsule # is started (or finished already) sync_status = capsule.content_get_sync() self.assertTrue( len(sync_status['active_sync_tasks']) >= 1 or sync_status['last_sync_time'] != last_sync_time) # Assert that packages count in the repository is updated self.assertEqual(repo.content_counts['package'], 3) # Assert that the content of the published content view in # lifecycle environment is exactly the same as content of the # repository cvv_repo_path = form_repo_path( org=org.label, cv=cv.label, cvv=cvv.version, prod=product.label, repo=repo.label, ) self.assertEqual( repo.content_counts['package'], cvv.package_count, ) self.assertEqual(get_repo_files(lce_repo_path), get_repo_files(cvv_repo_path)) # Wait till capsule sync finishes for task in sync_status['active_sync_tasks']: entities.ForemanTask(id=task['id']).poll() # Assert that the content published on the capsule is exactly the # same as in the repository self.assertEqual( get_repo_files(lce_repo_path, hostname=self.capsule_ip), get_repo_files(cvv_repo_path))