def test_all(self):
        """Create and sync a puppet repository with no feed."""
        cfg = config.get_config()
        if selectors.bug_is_untestable(2628, cfg.pulp_version):
            self.skipTest('https://pulp.plan.io/issues/2628')

        # Create a repository.
        client = api.Client(cfg, api.json_handler)
        repo = client.post(REPOSITORY_PATH, gen_repo())
        self.addCleanup(client.delete, repo['_href'])

        # Sync the repository. An error *should* occur. We just want the error
        # to be sane.
        with self.assertRaises(exceptions.TaskReportError) as err:
            utils.sync_repo(cfg, repo)
        with self.subTest(comment='check task "error" field'):
            self.assertIsNotNone(err.exception.task['error'])
            self.assertNotEqual(
                err.exception.task['error']['description'],
                "'NoneType' object has no attribute 'endswith'")
            self.assertNotEqual(err.exception.task['error']['code'], 'PLP0000')
        with self.subTest(comment='check task "exception" field'):
            self.assertIsNone(err.exception.task['exception'])
        with self.subTest(comment='check task "traceback" field'):
            self.assertIsNone(err.exception.task['traceback'])
    def test_non_matching_query(self):
        """Sync a repository with a query that doesn't match any units.

        Assert that:

        * None of the sync tasks has an error message.
        * Searching for module :data:`pulp_smash.constants.PUPPET_MODULE_2`
          yields no results.
        """
        # Create and sync a repository.
        client = api.Client(self.cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {
            'feed': PUPPET_FEED_2,
            'queries': [PUPPET_QUERY_2.replace('-', '_')],
        }
        body['distributors'] = [gen_distributor()]
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        self.sync_repo(repo)

        # Publish the repository.
        utils.publish_repo(self.cfg, repo)
        module = '/'.join((PUPPET_MODULE_2['author'], PUPPET_MODULE_2['name']))
        with self.assertRaises(HTTPError):
            client.get(
                '/v3/releases',
                auth=('repository', repo['id']),
                params={'module': module},
            )
 def setUpClass(cls):
     """Create a Puppet repository."""
     super(DuplicateUploadsTestCase, cls).setUpClass()
     unit = utils.http_get(PUPPET_MODULE_URL_1)
     import_params = {'unit_type_id': 'puppet_module'}
     repo = api.Client(cls.cfg).post(REPOSITORY_PATH, gen_repo()).json()
     cls.upload_import_unit_args = (cls.cfg, unit, import_params, repo)
     cls.resources.add(repo['_href'])
    def setUpClass(cls):
        """Create a puppet repository with an invalid feed and sync it."""
        super(SyncInvalidFeedTestCase, cls).setUpClass()
        client = api.Client(cls.cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {'feed': 'http://' + utils.uuid4()}
        repo = client.post(REPOSITORY_PATH, body)
        cls.resources.add(repo['_href'])

        # Trigger a repository sync and collect completed tasks.
        client.response_handler = api.code_handler
        cls.report = client.post(urljoin(repo['_href'], 'actions/sync/'))
        cls.tasks = list(api.poll_spawned_tasks(cls.cfg, cls.report.json()))
    def setUpClass(cls):
        """Create repository with the feed pointing to a valid manifest."""
        super(SyncValidManifestFeedTestCase, cls).setUpClass()
        client = api.Client(cls.cfg)
        body = gen_repo()
        body['importer_config'] = {
            'feed':
            'http://repos.fedorapeople.org/repos/pulp/pulp/demo_repos/puppet_manifest/modules/'  # noqa pylint:disable=line-too-long
        }
        repo = client.post(REPOSITORY_PATH, body).json()
        cls.resources.add(repo['_href'])

        # Trigger a repository sync and collect completed tasks.
        cls.report = utils.sync_repo(cls.cfg, repo)
        cls.tasks = list(api.poll_spawned_tasks(cls.cfg, cls.report.json()))
    def setUpClass(cls):
        """Create two puppet repositories, with and without feed URLs."""
        super(CreateTestCase, cls).setUpClass()
        cls.bodies = tuple((gen_repo() for _ in range(2)))
        cls.bodies[1]['importer_config'] = {
            'feed': 'http://' + utils.uuid4(),  # Pulp checks for a URI scheme
            'queries': [PUPPET_QUERY_2],
        }

        client = api.Client(cls.cfg, api.json_handler)
        cls.repos = []
        cls.importers_iter = []
        for body in cls.bodies:
            repo = client.post(REPOSITORY_PATH, body)
            cls.resources.add(repo['_href'])
            cls.repos.append(repo)
            cls.importers_iter.append(client.get(repo['_href'] + 'importers/'))
示例#7
0
    def test_all(self):
        """Test puppet_install_distributor.

        Do the following:

        1. Create a puppet repository with a puppet_install_distributor
        2. Upload a puppet module
        3. Publish the repository
        4. Check if the puppet_install_distributor config was properly used
        """
        cli_client = cli.Client(self.cfg)
        sudo = () if utils.is_root(self.cfg) else ('sudo', )

        # Create a directory and make sure Pulp can write to it.
        install_path = cli_client.run(('mktemp', '--directory')).stdout.strip()
        self.addCleanup(cli_client.run, sudo + ('rm', '-rf', install_path))
        cli_client.run(sudo + ('chown', 'apache:apache', install_path))
        cli_client.run(sudo + ('chcon', '-t', 'puppet_etc_t', install_path))

        # Make sure the pulp_manage_puppet boolean is enabled
        cli_client.run(sudo + ('semanage', 'boolean', '--modify', '--on',
                               'pulp_manage_puppet'))
        self.addCleanup(
            cli_client.run, sudo +
            ('semanage', 'boolean', '--modify', '--off', 'pulp_manage_puppet'))

        # Create and populate a Puppet repository.
        distributor = gen_install_distributor()
        distributor['distributor_config']['install_path'] = install_path
        body = gen_repo()
        body['distributors'] = [distributor]
        client = api.Client(self.cfg, api.json_handler)
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        unit = utils.http_get(PUPPET_MODULE_URL_1)
        utils.upload_import_unit(self.cfg, unit,
                                 {'unit_type_id': 'puppet_module'}, repo)

        # Publish, and verify the module is present. (Dir has 700 permissions.)
        utils.publish_repo(self.cfg, repo)
        proc = cli_client.run(sudo +
                              ('runuser', '--shell', '/bin/sh', '--command',
                               'ls -1 {}'.format(install_path), '-', 'apache'))
        self.assertIn(PUPPET_MODULE_1['name'], proc.stdout.split('\n'), proc)
    def test_matching_query(self):
        """Sync a repository with a query that matches units.

        Assert that:

        * None of the sync tasks has an error message.
        * Searching for module :data:`pulp_smash.constants.PUPPET_MODULE_2`
          yields one result.
        * The synced-in module can be downloaded.
        """
        # Create and sync a repository.
        client = api.Client(self.cfg, api.json_handler)
        body = gen_repo()
        body['importer_config'] = {
            'feed': PUPPET_FEED_2,
            'queries': [PUPPET_QUERY_2],
        }
        body['distributors'] = [gen_distributor()]
        repo = client.post(REPOSITORY_PATH, body)
        self.addCleanup(client.delete, repo['_href'])
        repo = client.get(repo['_href'], params={'details': True})
        self.sync_repo(repo)

        # Publish the repository.
        utils.publish_repo(self.cfg, repo)
        module = '/'.join((PUPPET_MODULE_2['author'], PUPPET_MODULE_2['name']))
        response = client.get(
            '/v3/releases',
            auth=('repository', repo['id']),
            params={'module': module},
        )
        self.assertEqual(len(response['results']), 1)

        # Download the Puppet module.
        module = utils.http_get(PUPPET_MODULE_URL_2)
        client.response_handler = api.safe_handler
        response = client.get(response['results'][0]['file_uri'])
        with self.subTest():
            self.assertEqual(module, response.content)
        with self.subTest():
            self.assertIn(response.headers['content-type'],
                          ('application/gzip', 'application/x-gzip'))
示例#9
0
    def test_all(self):
        """Creating a repo with an invalid distributor should throw an error.

        This test targets `Pulp #1237 <https://pulp.plan.io/issues/1237>`_.
        Do the following:

        1. Create a puppet repo
        2. Make an API call to create a distributor WITHOUT non-optional
            install_path
        3. Assert that an error is thrown
        4. Assert that no repo is created
        """
        if selectors.bug_is_untestable(1237, self.cfg.pulp_version):
            self.skipTest('https://pulp.plan.io/issues/1237')
        distributor = gen_install_distributor()
        distributor['distributor_config']['install_path'] = ''
        body = gen_repo()
        body['distributors'] = [distributor]
        client = api.Client(self.cfg, api.json_handler)
        with self.assertRaises(HTTPError):
            repo = client.post(REPOSITORY_PATH, body)
            self.addCleanup(client.delete, repo['_href'])
示例#10
0
    def setUpClass(cls):
        """Upload puppet module to a repo, copy it to another, publish and download.

        Create two puppet repositories, both without feeds. Upload an module to
        the first repository. Copy its content to the second repository. Add
        distributors to the repositories, publish repositories and download
        modules back from them.
        """
        super(PublishTestCase, cls).setUpClass()
        utils.reset_pulp(cls.cfg)  # See: https://pulp.plan.io/issues/1406
        cls.responses = {}
        cls.modules = []  # Raw puppet modules.

        # Download a puppet module and create two repositories.
        client = api.Client(cls.cfg, api.json_handler)
        repos = [client.post(REPOSITORY_PATH, gen_repo()) for _ in range(2)]
        for repo in repos:
            cls.resources.add(repo['_href'])
        client.response_handler = api.safe_handler
        cls.modules.append(utils.http_get(PUPPET_MODULE_URL_1))

        # Begin an upload request, upload a puppet module, move the puppet
        # module into a repository, and end the upload request.
        cls.responses['malloc'] = client.post(CONTENT_UPLOAD_PATH)
        cls.responses['upload'] = client.put(
            urljoin(cls.responses['malloc'].json()['_href'], '0/'),
            data=cls.modules[0],
        )
        cls.responses['import'] = client.post(
            urljoin(repos[0]['_href'], 'actions/import_upload/'),
            {
                'unit_key': {},
                'unit_type_id': 'puppet_module',
                'upload_id': cls.responses['malloc'].json()['upload_id'],
            },
        )
        cls.responses['free'] = client.delete(
            cls.responses['malloc'].json()['_href'])

        # Copy content from the first puppet repository to the second.
        cls.responses['copy'] = client.post(
            urljoin(repos[1]['_href'], 'actions/associate/'),
            {'source_repo_id': repos[0]['id']})

        # Add a distributor to each repository. Publish each repository.
        for key in {'distribute', 'publish'}:
            cls.responses[key] = []
        for repo in repos:
            cls.responses['distribute'].append(
                client.post(
                    urljoin(repo['_href'], 'distributors/'), {
                        'auto_publish': False,
                        'distributor_id': utils.uuid4(),
                        'distributor_type_id': 'puppet_distributor',
                        'distributor_config': {
                            'serve_http': True,
                            'serve_https': True,
                            'relative_url': '/' + utils.uuid4(),
                        },
                    }))
            cls.responses['publish'].append(
                client.post(
                    urljoin(repo['_href'], 'actions/publish/'),
                    {'id': cls.responses['distribute'][-1].json()['id']},
                ))

        # Query both distributors using all three query forms.
        cls.responses['puppet releases'] = []
        author_name = PUPPET_MODULE_1['author'] + '/' + PUPPET_MODULE_1['name']
        for repo in repos:
            if selectors.bug_is_untestable(1440, cls.cfg.pulp_version):
                continue
            cls.responses['puppet releases'].append(
                client.get(
                    '/api/v1/releases.json',
                    params={'module': author_name},
                    auth=('.', repo['id']),
                ))
            cls.responses['puppet releases'].append(
                client.get(
                    '/pulp_puppet/forge/repository/{}/api/v1/releases.json'.
                    format(repo['id']),
                    params={'module': author_name},
                ))
            if cls.cfg.pulp_version < Version('2.8'):
                continue
            cls.responses['puppet releases'].append(
                client.get(
                    '/v3/releases',
                    params={'module': author_name},
                    auth=('repository', repo['id']),
                ))

        # Download each unit referenced by the queries above.
        for response in cls.responses['puppet releases']:
            body = response.json()
            if set(body.keys()) == {'pagination', 'results'}:  # Puppet >= 3.6
                path = body['results'][0]['file_uri']
            else:
                path = body[author_name][0]['file']
            cls.modules.append(client.get(path).content)

        # Search for all units in each of the two repositories.
        cls.responses['repo units'] = [
            utils.search_units(cls.cfg, repo, {}, api.safe_handler)
            for repo in repos
        ]