class TestCircleCIApi(unittest.TestCase):
    def setUp(self):
        self.c = Api(os.getenv('CIRCLE_TOKEN'))

    def test_trigger_with_build_params(self):
        params = {"build_parameters[CIRCLE_JOB]": "integration"}

        resp = self.c.trigger_build('thomasrockhu',
                                    'circleci.py',
                                    params=params)

        self.assertEqual(resp['build_parameters']['CIRCLE_JOB'], 'integration')

    def test_add_ssh_key(self):

        # note this is a throwaway key
        key = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAr74mGZIij/V59DTGRPaijyDolWA33FlyopBVSys09MOOF7HT
EWLMwyyRIR3t6mjl7kcS3rTPWORLF4U+8iMv1EyitV+fV+pQIJmK8gZvyyNePCR0
wvAizhNTcYgtZF86D/EBNHwOdN0o4P+4qlbBlPjFiW7S5X6iDbrV9H4ADQDI2R+c
EBets+aVRrtCdR+cGrOS9BRVf4NK6ADQaKOcgTYRTJuxI48O18iUj9dZSCAlO6xQ
obpALlQKj0srGcx9++vTzED3Wr9JpOfsC8LqNdJdaF6KJfBsc1xczSw980hcXwWx
/zrQaii5W7nFU2lRrwdXyscqutL1I5lLKDYhLQIDAQABAoIBACA9mxG/3HVajGf/
sov+Ty5A1EprH3ReOIiYP/2NTKbGpW+1YMpkvLnlmC5iJj6FxgDjqxOOSie9ogUL
ndOgHusssADkLQBc7Rw97t6dza6Pq38PFRiaI1h49Srz15f9XFKGXTk6tRA9bn1w
jHk7d0IULXEcErald6dbKlszLmE0AHvWHWNrABwbNBzG2PrFFbrWbYiUDhIx8Ebj
9IKDu8JqYr5o6Kv8agOAWkq4S3iGQ9S+suTiV+3/kyK7XL5TI5gVPdZR4NIAGFKO
+1TBNtCiYl+LQ46km5cmirESTsObNM3JrF8VWBlVZoVrxZiIhYUAKrFzcJ905Vrh
PN0rwmECgYEA6LWeorGs9kyVgNI4KnvVI1AXACnpy4L48ypqIns5A71j+4OiVI64
dWAlHB64ZoMVVBqTCv/uiloqzlK+FCe8cxi3Xh/hBDmKmGZygpFoRdGwmNA+1CoA
DZftaswUQ64Qt8jc9HmQnufvkxniNAewRxuZDP462WgBwZhRe8hvUqUCgYEAwVT0
HojCaLm2TMY2XE9EzCHNF1XlfqzB0i0dJ4pQ2SZ8st1F8vkEjHsPEOURRkLzWFC4
A/QWFsmhv4UKpDplV5QV3S+FgbpzLdV64vUYBuo06OZGcJgCdtZyt6vGSB4f+mq2
VQt+j6ZYlI5nWwkz1Yvg8AmBemuXNFui8o/c9ekCgYB2vwa9+nBKFnZLj/n9I8d1
B49VFA4rPSAP5VrXUY2cbO4yD8+r2lAiBPeqy7pJBSbDDfRurn5otu4U7n/0BPrS
uJAJRbcq0rn4Xn6cRdqxlfjJYapN1UjFpvsNfinxB0ecoLCvR8EWdT/5DkIxTqMT
BfApgylAeyQ6R6F8yqCTyQKBgQCN5XFrO8scnDmt7ckWRWPkQ2bJGtVe/SMgxNXi
IIWoa7QYf4mIhLaO+P8c0lO0cw0yI8R7ulnADet2qwodcXLSLbFCb0+Y4KUK3eXc
0DD7WkjNK75Fg3xDhrAaGKxmYB3uaQY8MzyH6HqZRk+bpIxzzr+gzglHNdJ7rkpR
p79wiQKBgQCwFyjcLAfA5uJDZ9jVEZ2BKgd9IGo16HrRnd+mpggUBGf2mbE2JGgk
rAUZ8tU0o5Ec6T0ZQkcous7OwBZGE+JLuFa3S6JfISLw42brjQ9dE5mosm7m2d4H
3C9cAnmV6aJkTwT46OiNvUYZ8je5WP+4Kqb2ke9xw3ddk5X1n5AB4w==
-----END RSA PRIVATE KEY-----
"""
        resp = self.c.add_ssh_key('thomasrockhu',
                                  'circleci-sandbox',
                                  key,
                                  hostname='localhost')

        # there is no response when success, so we test to make sure
        # that there is no other message as well.
        self.assertTrue(len(resp) == 0)

    def test_get_user_info(self):
        # exercise a real "GET"
        resp = self.c.get_user_info()

        self.assertEqual(resp['login'], 'thomasrockhu')

    def test_clear_cache(self):
        # execrise a real "DELETE"
        resp = self.c.clear_cache('thomasrockhu', 'circleci-sandbox')

        self.assertEqual(resp['status'], 'build dependency caches deleted')

    def test_retry_build_no_cache(self):
        # use Experimental API
        self.e = Experimental(os.getenv('CIRCLE_TOKEN'))

        resp = self.e.retry_no_cache('thomasrockhu', 'circleci-sandbox', 1)

        self.assertTrue(resp['no_dependency_cache'])

    def test_add_heroku_key(self):
        key = os.getenv('HEROKU_KEY')

        resp = self.c.add_heroku_key(key)

        # there is no response when success, so we test to make sure
        # that there is no other message as well.
        self.assertTrue(len(resp) == 0)

    def test_download_artifact(self):
        resp = self.c.get_artifacts('thomasrockhu', 'circleci.py', 87)

        artifact = self.c.download_artifact(resp[0]['url'])

        self.assertIn('circleci_api_py.html', artifact)

        artifact_with_destdir = self.c.download_artifact(
            resp[0]['url'], '/tmp')

        self.assertIn('tmp', artifact_with_destdir)

        artifact_with_destdir_and_filename = self.c.download_artifact(
            resp[0]['url'], '/tmp', 'myartifact.txt')

        self.assertIn('myartifact.txt', artifact_with_destdir_and_filename)
Exemple #2
0
class TestCircleCIApi(unittest.TestCase):

    def setUp(self):
        self.c = Api(os.getenv('CIRCLE_TOKEN'))

    def loadMock(self, filename):
        """helper function to open mock responses"""
        filename = 'tests/mocks/{0}'.format(filename)

        with open(filename, 'r') as f:
            self.c._request = MagicMock(return_value=f.read())

    def test_bad_verb(self):

        with self.assertRaises(BadVerbError) as e:
            self.c._request('BAD', 'dummy')

        self.assertEqual('BAD', e.exception.argument)
        self.assertIn('DELETE', e.exception.message)

    def test_get_user_info(self):
        self.loadMock('mock_user_info_response')
        resp = json.loads(self.c.get_user_info())

        self.assertEqual(resp["selected_email"], '*****@*****.**')

    def test_get_projects(self):
        self.loadMock('mock_get_projects_response')
        resp = json.loads(self.c.get_projects())

        self.assertEqual(resp[0]['vcs_url'], 'MOCK+https://ghe-dev.circleci.com/ccie-tester/testing')

    def test_follow_project(self):
        self.loadMock('mock_follow_project_response')
        resp = json.loads(self.c.follow_project('ccie-tester', 'testing'))

        self.assertEqual(resp["mock+following"], True)

    def test_get_project_build_summary(self):
        self.loadMock('mock_project_build_summary_response')
        resp = json.loads(self.c.get_project_build_summary('ccie-tester', 'testing'))

        self.assertEqual(len(resp), 6)
        self.assertEqual(resp[0]['username'], 'MOCK+ccie-tester')

        # with invalid status filter
        with self.assertRaises(InvalidFilterError) as e:
            json.loads(self.c.get_project_build_summary('ccie-tester', 'testing', status_filter='dummy'))

        self.assertEqual('dummy', e.exception.argument)
        self.assertIn('running', e.exception.message)

        # with branch
        resp = json.loads(self.c.get_project_build_summary('ccie-tester', 'testing', branch='master'))

        self.assertEqual(len(resp), 6)
        self.assertEqual(resp[0]['username'], 'MOCK+ccie-tester')

    def test_get_recent_builds(self):
        self.loadMock('mock_get_recent_builds_response')
        resp = json.loads(self.c.get_recent_builds())

        self.assertEqual(len(resp), 7)
        self.assertEqual(resp[0]['reponame'], 'MOCK+testing')

    def test_get_build_info(self):
        self.loadMock('mock_get_build_info_response')
        resp = json.loads(self.c.get_build_info('ccie-tester', 'testing', '1'))

        self.assertEqual(resp['reponame'], 'MOCK+testing')

    def test_get_artifacts(self):
        self.loadMock('mock_get_artifacts_response')
        resp = json.loads(self.c.get_artifacts('ccie-tester', 'testing', '1'))

        self.assertEqual(resp[0]['path'], 'MOCK+raw-test-output/go-test-report.xml')

    def test_retry_build(self):
        self.loadMock('mock_retry_build_response')
        resp = json.loads(self.c.retry_build('ccie-tester', 'testing', '1'))

        self.assertEqual(resp['reponame'], 'MOCK+testing')

        # with SSH
        resp = json.loads(self.c.retry_build('ccie-tester', 'testing', '1', ssh=True))

        self.assertEqual(resp['reponame'], 'MOCK+testing')

    def test_cancel_build(self):
        self.loadMock('mock_cancel_build_response')
        resp = json.loads(self.c.cancel_build('ccie-tester', 'testing', '11'))

        self.assertEqual(resp['reponame'], 'MOCK+testing')
        self.assertEqual(resp['build_num'], 11)
        self.assertTrue(resp['canceled'])

    def test_add_ssh_user(self):
        self.loadMock('mock_add_ssh_user_response')
        resp = json.loads(self.c.add_ssh_user('ccie-tester', 'testing', '11'))

        self.assertEqual(resp['reponame'], 'MOCK+testing')
        self.assertEqual(resp['ssh_users'][0]['login'], 'ccie-tester')

    def test_trigger_build(self):
        self.loadMock('mock_trigger_build_response')
        resp = json.loads(self.c.trigger_build('ccie-tester', 'testing'))

        self.assertEqual(resp['reponame'], 'MOCK+testing')

    def test_list_checkout_keys(self):
        self.loadMock('mock_list_checkout_keys_response')
        resp = json.loads(self.c.list_checkout_keys('levlaz', 'circleci-sandbox'))

        self.assertEqual(resp[0]['type'], 'deploy-key')
        self.assertIn('public_key', resp[0])

    def test_create_checkout_key(self):

        with self.assertRaises(BadKeyError) as e:
            self.c.create_checkout_key('levlaz', 'test', 'bad')

        self.assertEqual('bad', e.exception.argument)
        self.assertIn('deploy-key', e.exception.message)

        self.loadMock('mock_create_checkout_key_response')
        resp = json.loads(self.c.create_checkout_key('levlaz', 'test', 'deploy-key'))

        self.assertEqual(resp['type'], 'deploy-key')
        self.assertIn('public_key', resp)

    def test_get_checkout_key(self):

        self.loadMock('mock_get_checkout_key_response')
        resp = json.loads(self.c.get_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e'))

        self.assertEqual(resp['type'], 'deploy-key')
        self.assertIn('public_key', resp)

    def test_delete_checkout_key(self):
        self.loadMock('mock_delete_checkout_key_response')
        resp = json.loads(self.c.delete_checkout_key('levlaz', 'circleci-sandbox', '94:19:ab:a9:f4:2b:21:1c:a5:87:dd:ee:3d:c2:90:4e'))

        self.assertEqual(resp['message'], 'ok')

    def test_clear_cache(self):
        self.loadMock('mock_clear_cache_response')
        resp = json.loads(self.c.clear_cache('levlaz', 'circleci-sandbox'))

        self.assertEqual('build dependency caches deleted', resp['status'])

    def test_get_test_metadata(self):
        self.loadMock('mock_get_test_metadata_response')
        resp = json.loads(self.c.get_test_metadata('levlaz', 'circleci-demo-javascript-express', 127))

        self.assertEqual(len(resp), 2)
        self.assertIn('tests', resp)

    def test_list_envvars(self):
        self.loadMock('mock_list_envvars_response')
        resp = json.loads(self.c.list_envvars('levlaz', 'circleci-sandbox'))

        self.assertEqual(len(resp), 4)
        self.assertEqual(resp[0]['name'], 'BAR')

    def test_add_envvar(self):
        self.loadMock('mock_add_envvar_response')
        resp = json.loads(self.c.add_envvar('levlaz', 'circleci-sandbox', 'foo', 'bar'))

        self.assertEqual(resp['name'], 'foo')
        self.assertNotEqual(resp['value'], 'bar')

    def test_get_envvar(self):
        self.loadMock('mock_get_envvar_response')
        resp = json.loads(self.c.get_envvar('levlaz', 'circleci-sandbox', 'foo'))

        self.assertEqual(resp['name'], 'foo')
        self.assertNotEqual(resp['value'], 'bar')

    def test_delete_envvar(self):
        self.loadMock('mock_delete_envvar_response')
        resp = json.loads(self.c.delete_envvar('levlaz', 'circleci-sandbox', 'foo'))

        self.assertEqual(resp['message'], 'ok')

    def test_get_latest_artifact(self):
        self.loadMock('mock_get_latest_artifacts_response')
        resp = json.loads(self.c.get_latest_artifact('levlaz', 'circleci-sandbox'))

        self.assertEqual(resp[0]['path'],'circleci-docs/index.html')

        resp = json.loads(self.c.get_latest_artifact('levlaz', 'circleci-sandbox', 'master'))
        self.assertEqual(resp[0]['path'],'circleci-docs/index.html')

        with self.assertRaises(InvalidFilterError):
            self.c.get_latest_artifact('levlaz', 'circleci-sandbox', 'master', 'invalid')