Пример #1
0
class TestCharmStore(TestCase):

    def entities_response(self, url, request):
        self.assertEqual(
            url.geturl(), 'http://example.com/meta/' +
            'any?include=id&id=wordpress&id=mysql')
        return {
            'status_code': 200,
            'content': b'{"wordpress":"wordpress","mysql":"mysql"}'}

    def setUp(self):
        self.cs = CharmStore('http://example.com')

    def test_init(self):
        self.assertEqual(self.cs.url, 'http://example.com')

    def test_entity(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entity_full_id(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM_ID)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entity_reference(self):
        with HTTMock(entity_200):
            data = self.cs.charm(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entities(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities(['wordpress', 'mysql'])
        self.assertEqual(
            {u'wordpress': u'wordpress', u'mysql': u'mysql'}, response)

    def test_entities_reference(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities(
                [references.Reference.from_string('wordpress'),
                 references.Reference.from_string('mysql')])
        self.assertEqual(
            {u'wordpress': u'wordpress', u'mysql': u'mysql'}, response)

    def test_entities_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound) as cm:
                self.cs.entities(['not-found'])
            self.assertEqual(
                'http://example.com/meta/any?include=id&id=not-found',
                cm.exception.args[0]
            )

    def test_charm_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_charm_error_id(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM_ID)

    def test_charm_error_407(self):
        with HTTMock(entity_407):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_config(self):
        with HTTMock(config_200):
            data = self.cs.config(SAMPLE_CHARM)
        self.assertEqual({'exists': True}, data)

    def test_config_reference(self):
        with HTTMock(config_200):
            data = self.cs.config(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'exists': True}, data)

    def test_config_error(self):
        with HTTMock(config_404):
            with self.assertRaises(EntityNotFound):
                self.cs.config(SAMPLE_CHARM)

    def test_archive_url(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(SAMPLE_CHARM)
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_archive_url_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_file_good(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM)
        self.assertEqual({
            u'icon.svg':
            u'http://example.com/precise/mysql-1/archive/icon.svg',
            u'README.md':
            u'http://example.com/precise/mysql-1/archive/README.md'
            },
            data)

    def test_file_good_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({
            u'icon.svg':
            u'http://example.com/precise/mysql-1/archive/icon.svg',
            u'README.md':
            u'http://example.com/precise/mysql-1/archive/README.md'
            },
            data)

    def test_file_error(self):
        with HTTMock(manifest_404):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM)

    def test_file_one_file(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM, filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md',
            data)

    def test_file_one_file_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM),
                filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md',
            data)

    def test_file_one_file_error(self):
        with HTTMock(manifest_200):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM, filename='does.not.exist.md')

    def test_file_read_file(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(
                    SAMPLE_CHARM, filename='README.md', read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_reference(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(
                    references.Reference.from_string(SAMPLE_CHARM),
                    filename='README.md',
                    read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_error(self):
        with HTTMock(manifest_200):
            with HTTMock(file_404):
                with self.assertRaises(EntityNotFound):
                    self.cs.files(
                        SAMPLE_CHARM, filename='readme.md', read_file=True)

    def test_entityId(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId('bar')
            self.assertEqual('foo/bar', charm_id)

    def test_entityId_reference(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId(
                references.Reference.from_string('bar'))
            self.assertEqual('foo/bar', charm_id)

    def test_ids_no_charm(self):
        with HTTMock(id_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entityId('baz')

    def test_search(self):
        with HTTMock(search_200):
            results = self.cs.search('foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list(self):
        with HTTMock(list_200):
            results = self.cs.list()
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_escaped(self):
        with HTTMock(search_200_escaped):
            results = self.cs.search('&foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.search('foo')
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/search?text=foo '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_list_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.list()
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/list '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_search_limit(self):
        with HTTMock(search_limit_200):
            results = self.cs.search('foo', limit=1)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_autocomplete(self):
        with HTTMock(search_autocomplete_200):
            results = self.cs.search(
                'foo', autocomplete=True)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_includes(self):
        with HTTMock(search_includes_200):
            results = self.cs.search(
                'foo', includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_includes(self):
        with HTTMock(list_includes_200):
            results = self.cs.list(includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_type(self):
        with HTTMock(search_type_200):
            results = self.cs.search('foo', doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_list_type(self):
        with HTTMock(list_type_200):
            results = self.cs.list(doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_search_tags(self):
        with HTTMock(search_tags_200):
            results = self.cs.search('foo', tags='databases')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_tags(self):
        with HTTMock(search_multiple_tags_200):
            results = self.cs.search('foo', tags=['databases', 'applications'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_series(self):
        with HTTMock(search_series_200):
            results = self.cs.search('foo', series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_series(self):
        with HTTMock(list_series_200):
            results = self.cs.list(series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_series(self):
        with HTTMock(search_multiple_series_200):
            results = self.cs.search('foo', series=['trusty', 'precise'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.search('', owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_list_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.list(owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_charm_icon_url(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(entity_id)
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_url_reference(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_ok(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(entity_id)
        self.assertEqual('icon', icon)

    def test_charm_icon_ok_reference(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(
                references.Reference.from_string(entity_id))
        self.assertEqual('icon', icon)

    def test_charm_icon_bad(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm_icon(entity_id)

    def test_bundle_visualization_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_ok(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(entity_id)
        self.assertEqual('diagram', diagram)

    def test_bundle_visualization_bad(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_404):
            with self.assertRaises(EntityNotFound):
                self.cs.bundle_visualization(entity_id)

    def test_bundle_visualization_reference(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(
                references.Reference.from_string(entity_id))
        self.assertEqual('diagram', diagram)

    def test_entity_readme_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_entity_readme_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_readme_not_found(self):
        # A 404 not found error is returned when the readme cannot be found.
        with HTTMock(readme_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entity_readme_content('precise/mysql-1')

    def test_readme_content(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content('precise/mysql-1')
            self.assertEqual('This is the readme', content)

    def test_readme_content_reference(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content(
                references.Reference.from_string('precise/mysql-1'))
            self.assertEqual('This is the readme', content)

    def test_debug(self):
        with HTTMock(debug_200):
            debug_data = self.cs.debug()
            self.assertEqual('all clear', debug_data['status'])

    def test_fetch_macaroon_successful(self):
        with HTTMock(fetch_macaroon_200):
            results = self.cs.fetch_macaroon()
            self.assertEqual('{"mymacaroon": "something"}', results)

    def test_fetch_macaroon_not_found(self):
        with HTTMock(fetch_macaroon_404):
            with self.assertRaises(EntityNotFound) as cm:
                self.cs.fetch_macaroon()
        self.assertEqual(cm.exception.args, ('http://example.com/macaroon',))

    def test_search_with_macaroon(self):
        with HTTMock(search_200_with_macaroon):
            self.cs.macaroons = "[macaroon1, macaroon2]"
            results = self.cs.search('foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_with_macaroon(self):
        with HTTMock(search_200_with_macaroon):
            self.cs.macaroons = "[macaroon1, macaroon2]"
            results = self.cs.list()
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_timeout(self):
        with HTTMock(search_timeout):
            with self.assertRaises(ServerError) as cm:
                self.cs.search('foo')
        message = cm.exception.args[0]
        self.assertTrue('Request timed out' in message)

    def test_resource_url(self):
        entity_id = 'mongodb'
        url = self.cs.resource_url(entity_id, "myresource", "22")
        self.assertEqual('http://example.com/mongodb/resource/myresource/22',
                         url)
Пример #2
0
class TestCharmStore(TestCase):

    def entities_response(self, url, request):
        self.assertEqual(
            url.geturl(), 'http://example.com/meta/' +
            'any?include=id&id=wordpress&id=mysql')
        return {
            'status_code': 200,
            'content': b'{"wordpress":"wordpress","mysql":"mysql"}'}

    def setUp(self):
        self.cs = CharmStore('http://example.com')

    def test_init(self):
        self.assertEqual(self.cs.url, 'http://example.com')

    def test_entity(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entity_full_id(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM_ID)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entity_reference(self):
        with HTTMock(entity_200):
            data = self.cs.charm(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entities(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities(['wordpress', 'mysql'])
        self.assertEqual(
            {u'wordpress': u'wordpress', u'mysql': u'mysql'}, response)

    def test_entities_reference(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities(
                [references.Reference.from_string('wordpress'),
                 references.Reference.from_string('mysql')])
        self.assertEqual(
            {u'wordpress': u'wordpress', u'mysql': u'mysql'}, response)

    def test_entities_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound) as cm:
                self.cs.entities(['not-found'])
            self.assertEqual(
                'http://example.com/meta/any?include=id&id=not-found',
                cm.exception.args[0]
            )

    def test_charm_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_charm_error_id(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM_ID)

    def test_charm_error_407(self):
        with HTTMock(entity_407):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_config(self):
        with HTTMock(config_200):
            data = self.cs.config(SAMPLE_CHARM)
        self.assertEqual({'exists': True}, data)

    def test_config_reference(self):
        with HTTMock(config_200):
            data = self.cs.config(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'exists': True}, data)

    def test_config_error(self):
        with HTTMock(config_404):
            with self.assertRaises(EntityNotFound):
                self.cs.config(SAMPLE_CHARM)

    def test_archive_url(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(SAMPLE_CHARM)
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_archive_url_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_file_good(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM)
        self.assertEqual({
            u'icon.svg':
            u'http://example.com/precise/mysql-1/archive/icon.svg',
            u'README.md':
            u'http://example.com/precise/mysql-1/archive/README.md'
            },
            data)

    def test_file_good_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({
            u'icon.svg':
            u'http://example.com/precise/mysql-1/archive/icon.svg',
            u'README.md':
            u'http://example.com/precise/mysql-1/archive/README.md'
            },
            data)

    def test_file_error(self):
        with HTTMock(manifest_404):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM)

    def test_file_one_file(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM, filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md',
            data)

    def test_file_one_file_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM),
                filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md',
            data)

    def test_file_one_file_error(self):
        with HTTMock(manifest_200):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM, filename='does.not.exist.md')

    def test_file_read_file(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(
                    SAMPLE_CHARM, filename='README.md', read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_reference(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(
                    references.Reference.from_string(SAMPLE_CHARM),
                    filename='README.md',
                    read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_error(self):
        with HTTMock(manifest_200):
            with HTTMock(file_404):
                with self.assertRaises(EntityNotFound):
                    self.cs.files(
                        SAMPLE_CHARM, filename='readme.md', read_file=True)

    def test_entityId(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId('bar')
            self.assertEqual('foo/bar', charm_id)

    def test_entityId_reference(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId(
                references.Reference.from_string('bar'))
            self.assertEqual('foo/bar', charm_id)

    def test_ids_no_charm(self):
        with HTTMock(id_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entityId('baz')

    def test_search(self):
        with HTTMock(search_200):
            results = self.cs.search('foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list(self):
        with HTTMock(list_200):
            results = self.cs.list()
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_escaped(self):
        with HTTMock(search_200_escaped):
            results = self.cs.search('&foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.search('foo')
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/search?text=foo '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_list_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.list()
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/list '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_search_limit(self):
        with HTTMock(search_limit_200):
            results = self.cs.search('foo', limit=1)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_autocomplete(self):
        with HTTMock(search_autocomplete_200):
            results = self.cs.search(
                'foo', autocomplete=True)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_includes(self):
        with HTTMock(search_includes_200):
            results = self.cs.search(
                'foo', includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_includes(self):
        with HTTMock(list_includes_200):
            results = self.cs.list(includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_type(self):
        with HTTMock(search_type_200):
            results = self.cs.search('foo', doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_list_type(self):
        with HTTMock(list_type_200):
            results = self.cs.list(doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_search_tags(self):
        with HTTMock(search_tags_200):
            results = self.cs.search('foo', tags='databases')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_tags(self):
        with HTTMock(search_multiple_tags_200):
            results = self.cs.search('foo', tags=['databases', 'applications'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_series(self):
        with HTTMock(search_series_200):
            results = self.cs.search('foo', series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_series(self):
        with HTTMock(list_series_200):
            results = self.cs.list(series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_series(self):
        with HTTMock(search_multiple_series_200):
            results = self.cs.search('foo', series=['trusty', 'precise'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.search('', owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_list_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.list(owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_charm_icon_url(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(entity_id)
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_url_reference(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_ok(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(entity_id)
        self.assertEqual('icon', icon)

    def test_charm_icon_ok_reference(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(
                references.Reference.from_string(entity_id))
        self.assertEqual('icon', icon)

    def test_charm_icon_bad(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm_icon(entity_id)

    def test_bundle_visualization_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_ok(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(entity_id)
        self.assertEqual('diagram', diagram)

    def test_bundle_visualization_bad(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_404):
            with self.assertRaises(EntityNotFound):
                self.cs.bundle_visualization(entity_id)

    def test_bundle_visualization_reference(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(
                references.Reference.from_string(entity_id))
        self.assertEqual('diagram', diagram)

    def test_entity_readme_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_entity_readme_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_readme_not_found(self):
        # A 404 not found error is returned when the readme cannot be found.
        with HTTMock(readme_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entity_readme_content('precise/mysql-1')

    def test_readme_content(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content('precise/mysql-1')
            self.assertEqual('This is the readme', content)

    def test_readme_content_reference(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content(
                references.Reference.from_string('precise/mysql-1'))
            self.assertEqual('This is the readme', content)

    def test_debug(self):
        with HTTMock(debug_200):
            debug_data = self.cs.debug()
            self.assertEqual('all clear', debug_data['status'])

    def test_timeout(self):
        with HTTMock(search_timeout):
            with self.assertRaises(ServerError) as cm:
                self.cs.search('foo')
        message = cm.exception.args[0]
        self.assertTrue('Request timed out' in message)

    def test_resource_url(self):
        entity_id = 'mongodb'
        url = self.cs.resource_url(entity_id, "myresource", "22")
        self.assertEqual('http://example.com/mongodb/resource/myresource/22',
                         url)
Пример #3
0
class TestCharmStore(TestCase):
    def entities_response(self, url, request):
        self.assertEqual(
            url.geturl(), 'http://example.com/meta/' +
            'any?include=id&id=wordpress&id=mysql')
        return {
            'status_code': 200,
            'content': b'{"wordpress":"wordpress","mysql":"mysql"}'
        }

    def setUp(self):
        self.cs = CharmStore('http://example.com')

    def test_init(self):
        self.assertEqual(self.cs.url, 'http://example.com')

    def test_entity(self):
        tests = [{
            'about':
            'default includes',
            'want_query':
            ('include=bundle-machine-count&include=bundle-metadata&'
             'include=bundle-unit-count&include=charm-actions&'
             'include=charm-config&include=charm-metadata&'
             'include=common-info&include=extra-info&include=owner&'
             'include=published&include=resources&'
             'include=supported-series&include=terms&include=stats'),
        }, {
            'about': 'custom includes',
            'kwargs': {
                'includes': ['foo', 'bar']
            },
            'want_query': 'include=foo&include=bar&include=stats',
        }, {
            'about': 'custom includes and no stats',
            'kwargs': {
                'includes': ['foo'],
                'include_stats': False
            },
            'want_query': 'include=foo',
        }, {
            'about': 'custom includes and get files',
            'kwargs': {
                'includes': [],
                'get_files': True
            },
            'want_query': 'include=manifest&include=stats',
        }, {
            'about':
            'default includes, no stats, with files',
            'kwargs': {
                'get_files': True,
                'include_stats': False
            },
            'want_query':
            ('include=bundle-machine-count&include=bundle-metadata&'
             'include=bundle-unit-count&include=charm-actions&'
             'include=charm-config&include=charm-metadata&'
             'include=common-info&include=extra-info&include=owner&'
             'include=published&include=resources&'
             'include=supported-series&include=terms&include=manifest'),
        }]
        for test in tests:
            # TODO(frankban): use subtests here when switching to Python 3.
            logging.debug(test['about'])
            self.check_entity(test.get('kwargs', {}),
                              test.get('want_query', ''))

    def check_entity(self, kwargs, want_query):
        @urlmatch(path=ID_PATH)
        def handler(url, request):
            self.assertEqual(request.method, 'GET')
            self.assertEqual(url.path, '/precise/mysql-1/meta/any')
            self.assertEqual(url.query, want_query)
            return {'status_code': 200, 'content': {'result': 'foo'}}

        with HTTMock(handler):
            data = self.cs.entity(SAMPLE_CHARM_ID, **kwargs)
        self.assertEqual(data, {'result': 'foo'})

    def test_charm(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_charm_full_id(self):
        with HTTMock(entity_200):
            data = self.cs.charm(SAMPLE_CHARM_ID)
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_charm_reference(self):
        with HTTMock(entity_200):
            data = self.cs.charm(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'Meta': {'charm-metadata': {'exists': True}}}, data)

    def test_entities(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities(['wordpress', 'mysql'])
        self.assertEqual({
            u'wordpress': u'wordpress',
            u'mysql': u'mysql'
        }, response)

    def test_entities_reference(self):
        with HTTMock(self.entities_response):
            response = self.cs.entities([
                references.Reference.from_string('wordpress'),
                references.Reference.from_string('mysql')
            ])
        self.assertEqual({
            u'wordpress': u'wordpress',
            u'mysql': u'mysql'
        }, response)

    def test_entities_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound) as cm:
                self.cs.entities(['not-found'])
            self.assertEqual(
                'http://example.com/meta/any?include=id&id=not-found',
                cm.exception.args[0])

    def test_charm_error(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_charm_error_id(self):
        with HTTMock(entity_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM_ID)

    def test_charm_error_407(self):
        with HTTMock(entity_407):
            with self.assertRaises(EntityNotFound):
                self.cs.charm(SAMPLE_CHARM)

    def test_config(self):
        with HTTMock(config_200):
            data = self.cs.config(SAMPLE_CHARM)
        self.assertEqual({'exists': True}, data)

    def test_config_reference(self):
        with HTTMock(config_200):
            data = self.cs.config(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual({'exists': True}, data)

    def test_config_error(self):
        with HTTMock(config_404):
            with self.assertRaises(EntityNotFound):
                self.cs.config(SAMPLE_CHARM)

    def test_archive_url(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(SAMPLE_CHARM)
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_archive_url_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.archive_url(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual(u'http://example.com/precise/mysql-1/archive', data)

    def test_file_good(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM)
        self.assertEqual(
            {
                u'icon.svg':
                u'http://example.com/precise/mysql-1/archive/icon.svg',
                u'README.md':
                u'http://example.com/precise/mysql-1/archive/README.md'
            }, data)

    def test_file_good_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM))
        self.assertEqual(
            {
                u'icon.svg':
                u'http://example.com/precise/mysql-1/archive/icon.svg',
                u'README.md':
                u'http://example.com/precise/mysql-1/archive/README.md'
            }, data)

    def test_file_error(self):
        with HTTMock(manifest_404):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM)

    def test_file_one_file(self):
        with HTTMock(manifest_200):
            data = self.cs.files(SAMPLE_CHARM, filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md', data)

    def test_file_one_file_reference(self):
        with HTTMock(manifest_200):
            data = self.cs.files(
                references.Reference.from_string(SAMPLE_CHARM),
                filename='README.md')
        self.assertEqual(
            u'http://example.com/precise/mysql-1/archive/README.md', data)

    def test_file_one_file_error(self):
        with HTTMock(manifest_200):
            with self.assertRaises(EntityNotFound):
                self.cs.files(SAMPLE_CHARM, filename='does.not.exist.md')

    def test_file_read_file(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(SAMPLE_CHARM,
                                     filename='README.md',
                                     read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_reference(self):
        with HTTMock(manifest_200):
            with HTTMock(file_200):
                data = self.cs.files(
                    references.Reference.from_string(SAMPLE_CHARM),
                    filename='README.md',
                    read_file=True)
        self.assertEqual('This is a file.', data)

    def test_file_read_file_error(self):
        with HTTMock(manifest_200):
            with HTTMock(file_404):
                with self.assertRaises(EntityNotFound):
                    self.cs.files(SAMPLE_CHARM,
                                  filename='readme.md',
                                  read_file=True)

    def test_entityId(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId('bar')
            self.assertEqual('foo/bar', charm_id)

    def test_entityId_reference(self):
        with HTTMock(id_200):
            charm_id = self.cs.entityId(
                references.Reference.from_string('bar'))
            self.assertEqual('foo/bar', charm_id)

    def test_ids_no_charm(self):
        with HTTMock(id_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entityId('baz')

    def test_search(self):
        with HTTMock(search_200):
            results = self.cs.search('foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list(self):
        with HTTMock(list_200):
            results = self.cs.list()
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_escaped(self):
        with HTTMock(search_200_escaped):
            results = self.cs.search('&foo')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.search('foo')
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/search?text=foo '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_list_400(self):
        with patch('theblues.charmstore.logging.error') as log_mocked:
            with HTTMock(search_400):
                with self.assertRaises(ServerError) as cm:
                    self.cs.list()
        self.assertEqual(400, cm.exception.args[0])
        log_mocked.assert_called_with(
            'Error during request: http://example.com/list '
            'status code:(400) message: '
            '{"Message": "invalid parameter: user", "Code": "bad request"}')

    def test_search_limit(self):
        with HTTMock(search_limit_200):
            results = self.cs.search('foo', limit=1)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_autocomplete(self):
        with HTTMock(search_autocomplete_200):
            results = self.cs.search('foo', autocomplete=True)
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_includes(self):
        with HTTMock(search_includes_200):
            results = self.cs.search(
                'foo', includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_includes(self):
        with HTTMock(list_includes_200):
            results = self.cs.list(includes=['archive-size', 'charm-metadata'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_type(self):
        with HTTMock(search_type_200):
            results = self.cs.search('foo', doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_list_type(self):
        with HTTMock(list_type_200):
            results = self.cs.list(doc_type='bundle')
            self.assertEqual([{'Id': 'cs:bundle/mediawiki-single-7'}], results)

    def test_search_tags(self):
        with HTTMock(search_tags_200):
            results = self.cs.search('foo', tags='databases')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_tags(self):
        with HTTMock(search_multiple_tags_200):
            results = self.cs.search('foo', tags=['databases', 'applications'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_series(self):
        with HTTMock(search_series_200):
            results = self.cs.search('foo', series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_list_series(self):
        with HTTMock(list_series_200):
            results = self.cs.list(series='precise')
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_multiple_series(self):
        with HTTMock(search_multiple_series_200):
            results = self.cs.search('foo', series=['trusty', 'precise'])
            self.assertEqual([{'Id': 'cs:foo/bar-0'}], results)

    def test_search_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.search('', owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_list_owner(self):
        with HTTMock(search_owner_200):
            results = self.cs.list(owner='hatch')
            self.assertEqual([{"Id": "cs:foo/bar-0"}], results)

    def test_charm_icon_url(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(entity_id)
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_url_reference(self):
        entity_id = 'mongodb'
        url = self.cs.charm_icon_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb/icon.svg', url)

    def test_charm_icon_ok(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(entity_id)
        self.assertEqual('icon', icon)

    def test_charm_icon_ok_reference(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_200):
            icon = self.cs.charm_icon(
                references.Reference.from_string(entity_id))
        self.assertEqual('icon', icon)

    def test_charm_icon_bad(self):
        entity_id = 'precise/mysql-1'
        with HTTMock(icon_404):
            with self.assertRaises(EntityNotFound):
                self.cs.charm_icon(entity_id)

    def test_bundle_visualization_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.bundle_visualization_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/diagram.svg', url)

    def test_bundle_visualization_ok(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(entity_id)
        self.assertEqual('diagram', diagram)

    def test_bundle_visualization_bad(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_404):
            with self.assertRaises(EntityNotFound):
                self.cs.bundle_visualization(entity_id)

    def test_bundle_visualization_reference(self):
        entity_id = 'mongodb-cluster'
        with HTTMock(diagram_200):
            diagram = self.cs.bundle_visualization(
                references.Reference.from_string(entity_id))
        self.assertEqual('diagram', diagram)

    def test_entity_readme_url(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(entity_id)
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_entity_readme_url_reference(self):
        entity_id = 'mongodb-cluster'
        url = self.cs.entity_readme_url(
            references.Reference.from_string(entity_id))
        self.assertEqual('http://example.com/mongodb-cluster/readme', url)

    def test_readme_not_found(self):
        # A 404 not found error is returned when the readme cannot be found.
        with HTTMock(readme_404):
            with self.assertRaises(EntityNotFound):
                self.cs.entity_readme_content('precise/mysql-1')

    def test_readme_content(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content('precise/mysql-1')
            self.assertEqual('This is the readme', content)

    def test_readme_content_reference(self):
        with HTTMock(readme_200):
            content = self.cs.entity_readme_content(
                references.Reference.from_string('precise/mysql-1'))
            self.assertEqual('This is the readme', content)

    def test_debug(self):
        with HTTMock(debug_200):
            debug_data = self.cs.debug()
            self.assertEqual('all clear', debug_data['status'])

    def test_timeout(self):
        with HTTMock(search_timeout):
            with self.assertRaises(ServerError) as cm:
                self.cs.search('foo')
        message = cm.exception.args[0]
        self.assertTrue('Request timed out' in message)

    def test_resource_url(self):
        entity_id = 'mongodb'
        url = self.cs.resource_url(entity_id, "myresource", "22")
        self.assertEqual('http://example.com/mongodb/resource/myresource/22',
                         url)