blob: 82614fe283e81d0aff0479309bbb5b0975db5194 [file]
import sys
import unittest
try:
import simplejson as json
except ImportError:
import json
from libcloud.py3 import httplib
from libcloud.py3 import urlparse
from libcloud.py3 import b
try:
parse_qsl = urlparse.parse_qsl
except AttributeError:
import cgi
parse_qsl = cgi.parse_qsl
from libcloud.common.cloudstack import CloudStackConnection, CloudStackResponse
from libcloud.common.types import MalformedResponseError
from test import MockHttpTestCase
async_delay = 0
class CloudStackMockDriver(object):
host = 'nonexistant.'
path = '/path'
async_poll_frequency = 0
name = 'fake'
async_delay = 0
class CloudStackCommonTest(unittest.TestCase):
def setUp(self):
CloudStackConnection.conn_classes = (None, CloudStackMockHttp)
self.connection = CloudStackConnection('apikey', 'secret',
host=CloudStackMockDriver.host)
self.connection.poll_interval = 0.0
self.driver = self.connection.driver = CloudStackMockDriver()
def test_sync_request_bad_response(self):
self.driver.path = '/bad/response'
try:
self.connection._sync_request('fake')
except Exception:
e = sys.exc_info()[1]
self.assertTrue(isinstance(e, MalformedResponseError))
return
self.assertTrue(False)
def test_sync_request(self):
self.driver.path = '/sync'
self.connection._sync_request('fake')
def test_async_request_successful(self):
self.driver.path = '/async/success'
result = self.connection._async_request('fake')
self.assertEqual(result, {'fake': 'result'})
def test_async_request_unsuccessful(self):
self.driver.path = '/async/fail'
try:
self.connection._async_request('fake')
except:
return
self.assertFalse(True)
def test_async_request_delayed(self):
global async_delay
self.driver.path = '/async/delayed'
async_delay = 2
self.connection._async_request('fake')
self.assertEqual(async_delay, 0)
def test_signature_algorithm(self):
cases = [
(
{
'command': 'listVirtualMachines'
}, 'z/a9Y7J52u48VpqIgiwaGUMCso0='
), (
{
'command': 'deployVirtualMachine',
'name': 'fred',
'displayname': 'George',
'serviceofferingid': 5,
'templateid': 17,
'zoneid': 23,
'networkids': 42
}, 'gHTo7mYmadZ+zluKHzlEKb1i/QU='
), (
{
'command': 'deployVirtualMachine',
'name': 'fred',
'displayname': 'George+Ringo',
'serviceofferingid': 5,
'templateid': 17,
'zoneid': 23,
'networkids': 42
}, 'tAgfrreI1ZvWlWLClD3gu4+aKv4='
)
]
connection = CloudStackConnection('fnord', 'abracadabra')
for case in cases:
params = connection.add_default_params(case[0])
self.assertEqual(connection._make_signature(params), b(case[1]))
class CloudStackMockHttp(MockHttpTestCase):
def _response(self, status, result, response):
return (status, json.dumps(result), result, response)
def _check_request(self, url):
url = urlparse.urlparse(url)
query = dict(parse_qsl(url.query))
self.assertTrue('apiKey' in query)
self.assertTrue('command' in query)
self.assertTrue('response' in query)
self.assertTrue('signature' in query)
self.assertTrue(query['response'] == 'json')
return query
def _bad_response(self, method, url, body, headers):
self._check_request(url)
result = {'success': True}
return self._response(httplib.OK, result, httplib.responses[httplib.OK])
def _sync(self, method, url, body, headers):
query = self._check_request(url)
result = {query['command'].lower() + 'response': {}}
return self._response(httplib.OK, result, httplib.responses[httplib.OK])
def _async_success(self, method, url, body, headers):
query = self._check_request(url)
if query['command'].lower() == 'queryasyncjobresult':
self.assertEqual(query['jobid'], '42')
result = {
query['command'].lower() + 'response': {
'jobstatus': 1,
'jobresult': {'fake': 'result'}
}
}
else:
result = {query['command'].lower() + 'response': {'jobid': '42'}}
return self._response(httplib.OK, result, httplib.responses[httplib.OK])
def _async_fail(self, method, url, body, headers):
query = self._check_request(url)
if query['command'].lower() == 'queryasyncjobresult':
self.assertEqual(query['jobid'], '42')
result = {
query['command'].lower() + 'response': {
'jobstatus': 2,
'jobresult': {'fake': 'failresult'}
}
}
else:
result = {query['command'].lower() + 'response': {'jobid': '42'}}
return self._response(httplib.OK, result, httplib.responses[httplib.OK])
def _async_delayed(self, method, url, body, headers):
global async_delay
query = self._check_request(url)
if query['command'].lower() == 'queryasyncjobresult':
self.assertEqual(query['jobid'], '42')
if async_delay == 0:
result = {
query['command'].lower() + 'response': {
'jobstatus': 1,
'jobresult': {'fake': 'result'}
}
}
else:
result = {
query['command'].lower() + 'response': {
'jobstatus': 0,
}
}
async_delay -= 1
else:
result = {query['command'].lower() + 'response': {'jobid': '42'}}
return self._response(httplib.OK, result, httplib.responses[httplib.OK])
if __name__ == '__main__':
sys.exit(unittest.main())