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)
Example #2
0
    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)
Example #3
0
    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
        )
Example #5
0
    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)
            ))
Example #6
0
    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'])
Example #10
0
    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)
Example #13
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'))
Example #14
0
    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)
Example #15
0
    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),
        )
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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)
Example #19
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)
Example #20
0
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']
Example #21
0
    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)
Example #22
0
    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)
Example #24
0
    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)
Example #25
0
    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)
            )
Example #26
0
    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)
Example #28
0
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)
Example #29
0
    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)
Example #30
0
 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)
Example #31
0
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
Example #32
0
    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)
Example #33
0
    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)
Example #34
0
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
Example #35
0
    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)
Example #36
0
    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)
Example #39
0
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]
Example #40
0
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
Example #41
0
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)
Example #43
0
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
Example #46
0
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']
Example #47
0
    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
Example #49
0
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
Example #50
0
    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)
Example #51
0
    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}))
Example #52
0
    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)
Example #53
0
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'
Example #54
0
    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)
Example #55
0
    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
Example #56
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)
Example #57
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)
Example #58
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])
Example #59
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)
Example #60
0
    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))