Fix broken tests from refactor
diff --git a/.coveragerc b/.coveragerc
index c35bfbc..ac30c60 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -6,6 +6,7 @@
*__main__*
gstack/models/*.py
gstack/configure.py
+ gstack/core.py
[report]
exclude_lines =
diff --git a/gstack/controllers/disks.py b/gstack/controllers/disks.py
index 16a1a0c..4ce196e 100644
--- a/gstack/controllers/disks.py
+++ b/gstack/controllers/disks.py
@@ -42,11 +42,7 @@
machinetype=cloudstack_response['name'],
zone=zone
))
-
- if not zone:
- response['zone'] = cloudstack_response['zonename']
- else:
- response['zone'] = zone
+ response['zone'] = zone
return response
@@ -55,9 +51,10 @@
@authentication.required
def aggregatedlistdisks(projectid, authorization):
args = {'command':'listVolumes'}
+ kwargs = {'projectid':projectid}
items = controllers.describe_items_aggregated(
- authorization, args, 'volume',
- projectid, _cloudstack_volume_to_gce)
+ authorization, args, 'volume', 'disk',
+ _cloudstack_volume_to_gce, **kwargs)
populated_response = {
'kind': 'compute#diskAggregatedList',
@@ -73,9 +70,10 @@
@authentication.required
def listdisks(projectid, authorization, zone):
args = {'command':'listVolumes'}
+ kwargs = {'projectid':projectid, 'zone':zone}
items = controllers.describe_items(
authorization, args, 'volume',
- projectid, zone, _cloudstack_volume_to_gce)
+ _cloudstack_volume_to_gce, **kwargs)
populated_response = {
'kind': 'compute#imageList',
@@ -90,24 +88,9 @@
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/disks/<disk>', methods=['GET'])
@authentication.required
def getdisk(projectid, authorization, zone, disk):
- response = get_disk_by_name(
- authorization=authorization,
- disk=disk
- )
-
- if response:
- return helpers.create_response(
- data=_cloudstack_volume_to_gce(
- cloudstack_response=response,
- projectid=projectid,
- zone=zone
- )
- )
- else:
- func_route = url_for(
- 'getdisk',
- projectid=projectid,
- zone=zone,
- disk=disk
- )
- return errors.resource_not_found(func_route)
+ func_route = url_for('getdisk', projectid=projectid, zone=zone, disk=disk)
+ args = {'command':'listVolumes'}
+ kwargs = {'projectid':projectid, 'zone':zone}
+ return controllers.get_item_with_name_or_error(
+ authorization, disk, args, 'volume', func_route,
+ _cloudstack_volume_to_gce, **kwargs)
diff --git a/gstack/controllers/images.py b/gstack/controllers/images.py
index 6f5d226..49ab9ff 100755
--- a/gstack/controllers/images.py
+++ b/gstack/controllers/images.py
@@ -25,10 +25,15 @@
from gstack.controllers import errors
from flask import request, url_for
+def get_template_by_name(authorization, image):
+ args = {'templatefilter': 'executable', 'command':'listTemplates'}
+ return controllers.get_item_with_name(authorization, image, args, 'template')
+
def _create_populated_image_response(projectid, images=None):
if not images:
images = []
+
populated_response = {
'kind': 'compute#imageList',
'selfLink': request.base_url,
@@ -84,15 +89,8 @@
@app.route('/compute/v1/projects/<projectid>/global/images/<image>', methods=['GET'])
@authentication.required
def getimage(projectid, authorization, image):
- response = get_template_by_name(
- authorization=authorization,
- image=image
- )
-
- if response:
- return helpers.create_response(
- data=_cloudstack_template_to_gce(response)
- )
- else:
- func_route = url_for('getimage', projectid=projectid, image=image)
- return errors.resource_not_found(func_route)
\ No newline at end of file
+ func_route = url_for('getimage', projectid=projectid, image=image)
+ args = {'templatefilter': 'executable', 'command':'listTemplates'}
+ return controllers.get_item_with_name_or_error(
+ authorization, image, args, 'template', func_route,
+ _cloudstack_template_to_gce, **{})
\ No newline at end of file
diff --git a/gstack/controllers/instances.py b/gstack/controllers/instances.py
index b11eadb..4b9d22f 100755
--- a/gstack/controllers/instances.py
+++ b/gstack/controllers/instances.py
@@ -70,26 +70,6 @@
return cloudstack_response
-def _destroy_virtual_machine(authorization, instance):
- virtual_machine_id = _get_virtual_machine_by_name(
- authorization,
- instance)['id']
-
- if virtual_machine_id is None:
- func_route = url_for('_destroy_virtual_machine', instance=instance)
- return errors.resource_not_found(func_route)
-
- args = {
- 'id': virtual_machine_id
- }
- return requester.make_request(
- 'destroyVirtualMachine',
- args,
- authorization.client_id,
- authorization.client_secret
- )
-
-
def _cloudstack_virtual_machine_to_gce(cloudstack_response, projectid, zone, **kwargs):
response = {}
response['kind'] = 'compute#instance'
@@ -170,16 +150,6 @@
return helpers.create_response(data=populated_response)
-@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances/<instance>', methods=['GET'])
-@authentication.required
-def getinstance(projectid, authorization, zone, instance):
- func_route = url_for('getinstance', projectid=projectid, zone=zone, instance=instance)
- args = {'command':'listVirtualMachines'}
- return controllers.get_item_with_name_or_error(
- authorization, instance, args, 'zone', func_route,
- _cloudstack_zone_to_gce, **{'projectid':projectid})
-
-
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances', methods=['POST'])
@authentication.required
def addinstance(authorization, projectid, zone):
@@ -224,7 +194,21 @@
@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances/<instance>', methods=['DELETE'])
@authentication.required
def deleteinstance(projectid, authorization, zone, instance):
- deletion_result = _destroy_virtual_machine(authorization, instance)
+ args = {'command':'listVirtualMachines'}
+ virtual_machine = controllers.get_item_with_name(authorization, instance, args, 'virtualmachine')
+ if virtual_machine is None:
+ func_route = url_for('deleteinstance', projectid=projectid, zone=zone, instance=instance)
+ return errors.resource_not_found(func_route)
+
+ virtual_machine_id = virtual_machine['id']
+ args = {'id': virtual_machine_id}
+
+ deletion_result = requester.make_request(
+ 'destroyVirtualMachine',
+ args,
+ authorization.client_id,
+ authorization.client_secret
+ )
populated_response = operations.create_response(
projectid=projectid,
@@ -232,4 +216,14 @@
authorization=authorization
)
- return helpers.create_response(data=populated_response)
\ No newline at end of file
+ return helpers.create_response(data=populated_response)
+
+@app.route('/compute/v1/projects/<projectid>/zones/<zone>/instances/<instance>', methods=['GET'])
+@authentication.required
+def getinstance(projectid, authorization, zone, instance):
+ func_route = url_for('getinstance', projectid=projectid, zone=zone, instance=instance)
+ args = {'command':'listVirtualMachines'}
+ kwargs = {'projectid':projectid, 'zone':zone}
+ return controllers.get_item_with_name_or_error(
+ authorization, instance, args, 'virtualmachine', func_route,
+ _cloudstack_virtual_machine_to_gce, **kwargs)
\ No newline at end of file
diff --git a/gstack/controllers/machine_type.py b/gstack/controllers/machine_type.py
index 719d9a4..202a86e 100755
--- a/gstack/controllers/machine_type.py
+++ b/gstack/controllers/machine_type.py
@@ -25,6 +25,10 @@
from gstack.controllers import errors, zones
from flask import request, url_for
+def get_machinetype_by_name(authorization, machinetype):
+ args = {'command':'listServiceOfferings'}
+ return controllers.get_item_with_name(authorization, machinetype, args, 'serviceoffering')
+
def _cloudstack_service_offering_to_gce(cloudstack_response, projectid, zone):
response = {}
diff --git a/gstack/controllers/networks.py b/gstack/controllers/networks.py
index e101fd6..5932de1 100644
--- a/gstack/controllers/networks.py
+++ b/gstack/controllers/networks.py
@@ -26,6 +26,10 @@
from gstack.services import requester
from gstack.controllers import errors
+def get_network_by_name(authorization, network):
+ args = {'command':'SecurityGroups'}
+ return controllers.get_item_with_name(authorization, network, args, 'securitygroup')
+
def _add_network(authorization, args=None):
command = 'createSecurityGroup'
if not args:
diff --git a/gstack/controllers/zones.py b/gstack/controllers/zones.py
index e515777..213ec50 100755
--- a/gstack/controllers/zones.py
+++ b/gstack/controllers/zones.py
@@ -24,6 +24,10 @@
from gstack.services import requester
from gstack.controllers import errors
+def get_zone_by_name(authorization, zone):
+ args = {'command':'listZones'}
+ return controllers.get_item_with_name(authorization, zone, args, 'zone')
+
def _get_zones(authorization, args=None):
command = 'listZones'
@@ -42,8 +46,6 @@
def get_zone_names(authorization):
zone_list = _get_zones(authorization)
- print zone_list
-
zones = []
if zone_list['listzonesresponse']:
for zone in zone_list['listzonesresponse']['zone']:
diff --git a/tests/data/valid_get_image.json b/tests/data/valid_get_image.json
new file mode 100644
index 0000000..3348483
--- /dev/null
+++ b/tests/data/valid_get_image.json
@@ -0,0 +1,28 @@
+{
+ "domain": "ROOT",
+ "domainid": "2edae3e4-95e4-11e3-b2e4-d19c9d3e5e1d",
+ "ostypename": "CentOS 5.3 (32-bit)",
+ "zoneid": "1e47a2fc-61c7-401c-b90e-416b472ada64",
+ "displaytext": "CentOS 5.3(64-bit) no GUI (Simulator)",
+ "ostypeid": "2e678976-95e4-11e3-b2e4-d19c9d3e5e1d",
+ "passwordenabled": false,
+ "id": "a32d70ee-95e4-11e3-b2e4-d19c9d3e5e1d",
+ "size": 2147483648,
+ "isready": true,
+ "format": "VHD",
+ "templatetype": "BUILTIN",
+ "crosszones": true,
+ "zonename": "Sandbox-simulator",
+ "status": "Download Complete",
+ "isdynamicallyscalable": false,
+ "tags": [],
+ "isfeatured": true,
+ "sshkeyenabled": false,
+ "isextractable": false,
+ "account": "system",
+ "name": "imagename",
+ "created": "2014-02-15T02:50:13+0000",
+ "hypervisor": "Simulator",
+ "ispublic": true,
+ "checksum": ""
+}
\ No newline at end of file
diff --git a/tests/data/valid_get_instance.json b/tests/data/valid_get_instance.json
new file mode 100644
index 0000000..528cba4
--- /dev/null
+++ b/tests/data/valid_get_instance.json
@@ -0,0 +1,104 @@
+{
+ "domain": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "haenable": false,
+ "templatename": "Linux CentOS 6.5 64-bit",
+ "securitygroup": [
+ {
+ "egressrule": [],
+ "account": "brogand93@darrenbrogan.ie",
+ "description": "Default Security Group",
+ "tags": [],
+ "ingressrule": [],
+ "id": "6033ff41-53ff-4443-b0bb-f6c5c0191c34",
+ "name": "default"
+ }
+ ],
+ "zoneid": "1128bd56-b4d9-4ac6-a7b9-c715b187ce11",
+ "keypair": "brogand93@darrenbrogan.ie",
+ "cpunumber": 1,
+ "passwordenabled": true,
+ "id": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "displayvm": true,
+ "state": "Running",
+ "guestosid": "113038d0-a8cd-4d20-92be-ea313f87c3ac",
+ "memory": 1024,
+ "serviceofferingid": "b6cd1ff5-3a2f-4e9d-a4d1-8988c1191fe8",
+ "zonename": "ch-gva-2",
+ "isdynamicallyscalable": false,
+ "displayname": "foobar",
+ "tags": [
+ {
+ "account": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "resourcetype": "UserVm",
+ "resourceid": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "domain": "brogand93@darrenbrogan.ie",
+ "value": "root:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDqAuui+xCVPXaFD4cP2MuWnDlktg9vMT/SNzF17UiAzKEbxT/mNayTDAr",
+ "key": "0-sshkey-segment"
+ },
+ {
+ "account": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "resourcetype": "UserVm",
+ "resourceid": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "domain": "brogand93@darrenbrogan.ie",
+ "value": "DbY/BgGYC5bHuGlb/eE1r4EGpwSXZitGkTI4ThldrSp0Em7psO8AibdpYrFxlOmDFp9wKVD6xbY2HT1ySwvKi+ZwSR5yHcEKq15e",
+ "key": "1-sshkey-segment"
+ },
+ {
+ "account": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "resourcetype": "UserVm",
+ "resourceid": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "domain": "brogand93@darrenbrogan.ie",
+ "value": "V4eez/3qC1vIcssKmwu5+ZBneZAvWAfxHEKsQU0dsCVvHdn8g7tFXXtg4QCGtE4yzK5v3/+f1AdtIi4hvJoMyi8MV0KSa8e/ravd",
+ "key": "2-sshkey-segment"
+ },
+ {
+ "account": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "resourcetype": "UserVm",
+ "resourceid": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "domain": "brogand93@darrenbrogan.ie",
+ "value": "Hbgj44PncFBB8O6epVdXPbClZwtkz9D6GEQaOArxk9tX8YEgTFnmsnNuaoZgs7giMj2N7jQe2qXh5R0nsTTuH brogand@microv",
+ "key": "3-sshkey-segment"
+ },
+ {
+ "account": "brogand93@darrenbrogan.ie",
+ "domainid": "42f2b0d0-3953-485f-984d-b8d67185d358",
+ "resourcetype": "UserVm",
+ "resourceid": "71f13c6d-1590-4e82-9cdd-22eb9bcad0db",
+ "domain": "brogand93@darrenbrogan.ie",
+ "value": "ac",
+ "key": "4-sshkey-segment"
+ }
+ ],
+ "nic": [
+ {
+ "networkid": "00304a04-c7ea-4e77-a786-18bc64347bf7",
+ "macaddress": "06:b0:2e:00:01:04",
+ "isolationuri": "ec2://untagged",
+ "networkname": "guestNetworkForBasicZone",
+ "gateway": "185.19.28.1",
+ "traffictype": "Guest",
+ "broadcasturi": "vlan://untagged",
+ "netmask": "255.255.254.0",
+ "type": "Shared",
+ "ipaddress": "185.19.28.199",
+ "id": "2b5cc781-d310-43cf-9d68-66719f43855d",
+ "isdefault": true
+ }
+ ],
+ "cpuspeed": 2198,
+ "templateid": "c34bf3f0-318b-4d77-b0ca-f20585d05d32",
+ "affinitygroup": [],
+ "account": "brogand93@darrenbrogan.ie",
+ "name": "instancename",
+ "created": "2014-06-02T21:11:52+0200",
+ "hypervisor": "KVM",
+ "rootdevicetype": "ROOT",
+ "rootdeviceid": 0,
+ "serviceofferingname": "Tiny",
+ "templatedisplaytext": "Linux CentOS 6.5 64-bit 10GB Disk"
+ }
\ No newline at end of file
diff --git a/tests/data/valid_get_service_offering.json b/tests/data/valid_get_service_offering.json
new file mode 100644
index 0000000..a5381c0
--- /dev/null
+++ b/tests/data/valid_get_service_offering.json
@@ -0,0 +1,16 @@
+{
+ "iscustomized": false,
+ "name": "machinetypename",
+ "created": "2013-02-08T17:20:17+0100",
+ "storagetype": "local",
+ "limitcpuuse": false,
+ "cpuspeed": 2198,
+ "offerha": false,
+ "isvolatile": false,
+ "cpunumber": 1,
+ "memory": 512,
+ "displaytext": "Micro 512mb 1cpu",
+ "issystem": false,
+ "id": "71004023-bb72-4a97-b1e9-bc66dfce9470",
+ "defaultuse": false
+}
\ No newline at end of file
diff --git a/tests/data/valid_get_zone.json b/tests/data/valid_get_zone.json
new file mode 100644
index 0000000..4f438e3
--- /dev/null
+++ b/tests/data/valid_get_zone.json
@@ -0,0 +1,10 @@
+{
+ "localstorageenabled": true,
+ "name": "zonename",
+ "zonetoken": "ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7",
+ "securitygroupsenabled": true,
+ "allocationstate": "Enabled",
+ "dhcpprovider": "VirtualRouter",
+ "networktype": "Basic",
+ "id": "1128bd56-b4d9-4ac6-a7b9-c715b187ce11"
+}
\ No newline at end of file
diff --git a/tests/instances_tests.py b/tests/instances_tests.py
index 9420adc..4278caa 100644
--- a/tests/instances_tests.py
+++ b/tests/instances_tests.py
@@ -11,7 +11,6 @@
class InstancesTestCase(GStackAppTestCase):
def test_list_instances(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_describe_instances.json')
get.return_value.status_code = 200
@@ -23,7 +22,6 @@
self.assert_ok(response)
def test_aggregated_list_instances(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_describe_instances.json')
get.return_value.status_code = 200
@@ -42,7 +40,6 @@
self.assert_ok(response)
def test_list_instances_with_name_filter(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_describe_instance.json')
get.return_value.status_code = 200
@@ -56,7 +53,6 @@
self.assert_ok(response)
def test_aggregated_list_instances_with_name_filter(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_describe_instance.json')
get.return_value.status_code = 200
@@ -77,7 +73,6 @@
self.assert_ok(response)
def test_get_instance(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_describe_instance.json')
get.return_value.status_code = 200
@@ -89,7 +84,6 @@
self.assert_ok(response)
def test_get_instance_instance_not_found(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/empty_describe_instances.json')
get.return_value.status_code = 200
@@ -103,13 +97,12 @@
in response.data
def test_delete_instance(self):
-
get = mock.Mock()
get.return_value.text = read_file('tests/data/valid_async_destroy_vm.json')
get.return_value.status_code = 200
- get_instance_id = mock.Mock()
- get_instance_id.return_value = {'id':'virtualmachineid'}
+ get_instance = mock.Mock()
+ get_instance.return_value = json.loads(read_file('tests/data/valid_get_instance.json'))
get_async_result = mock.Mock()
get_async_result.return_value = json.loads(read_file('tests/data/valid_run_instance.json'))
@@ -118,8 +111,8 @@
with mock.patch('requests.get', get):
with mock.patch(
- 'gstack.controllers.instances._get_virtual_machine_by_name',
- get_instance_id
+ 'gstack.controllers.get_item_with_name',
+ get_instance
):
with mock.patch(
'gstack.controllers.operations._get_async_result',
@@ -130,6 +123,33 @@
self.assert_ok(response)
+ def test_delete_instance_instance_not_found(self):
+ get = mock.Mock()
+ get.return_value.text = read_file('tests/data/valid_async_destroy_vm.json')
+ get.return_value.status_code = 200
+
+ get_instance = mock.Mock()
+ get_instance.return_value = None
+
+ get_async_result = mock.Mock()
+ get_async_result.return_value = json.loads(read_file('tests/data/valid_run_instance.json'))
+
+ publickey_storage['admin'] = 'testkey'
+
+ with mock.patch('requests.get', get):
+ with mock.patch(
+ 'gstack.controllers.get_item_with_name',
+ get_instance
+ ):
+ with mock.patch(
+ 'gstack.controllers.operations._get_async_result',
+ get_async_result
+ ):
+ headers = {'authorization': 'Bearer ' + str(GStackAppTestCase.access_token)}
+ response = self.delete('/compute/v1/projects/admin/zones/examplezone/instances/instancename', headers=headers)
+
+ self.assert_not_found(response)
+
def test_add_instance(self):
data = {
'kind': 'compte#instance',
@@ -172,35 +192,35 @@
get.return_value.status_code = 200
get_templates = mock.Mock()
- get_templates.return_value = json.loads(read_file('tests/data/valid_describe_images.json'))
+ get_templates.return_value = json.loads(read_file('tests/data/valid_get_image.json'))
get_zones = mock.Mock()
- get_zones.return_value = json.loads(read_file('tests/data/valid_describe_zone.json'))
+ get_zones.return_value = json.loads(read_file('tests/data/valid_get_zone.json'))
get_service_offerings = mock.Mock()
- get_service_offerings.return_value = json.loads(read_file('tests/data/valid_describe_service_offering.json'))
+ get_service_offerings.return_value = json.loads(read_file('tests/data/valid_get_service_offering.json'))
get_networks = mock.Mock()
- get_networks.return_value = json.loads(read_file('tests/data/valid_describe_security_group.json'))
+ get_networks.return_value = json.loads(read_file('tests/data/valid_get_security_group.json'))
get_async_result = mock.Mock()
get_async_result.return_value = json.loads(read_file('tests/data/valid_run_instance.json'))
with mock.patch('requests.get', get):
with mock.patch(
- 'gstack.controllers.images._get_templates',
+ 'gstack.controllers.images.get_template_by_name',
get_templates
):
with mock.patch(
- 'gstack.controllers.zones._get_zones',
+ 'gstack.controllers.zones.get_zone_by_name',
get_zones
):
with mock.patch(
- 'gstack.controllers.machine_type._get_machinetypes',
+ 'gstack.controllers.machine_type.get_machinetype_by_name',
get_service_offerings
):
with mock.patch(
- 'gstack.controllers.networks._get_networks',
+ 'gstack.controllers.networks.get_network_by_name',
get_networks
):
with mock.patch(
diff --git a/tests/networks_tests.py b/tests/networks_tests.py
index 452d3a8..d88aa82 100644
--- a/tests/networks_tests.py
+++ b/tests/networks_tests.py
@@ -100,7 +100,7 @@
get.return_value.status_code = 200
get_networks = mock.Mock()
- get_networks.return_value = None
+ get_networks.return_value = json.loads(read_file('tests/data/valid_get_security_group.json'))
with mock.patch('requests.get', get):
with mock.patch('gstack.controllers.get_item_with_name', get_networks):
@@ -119,7 +119,7 @@
get.return_value.status_code = 200
get_networks = mock.Mock()
- get_networks.return_value = json.loads(read_file('tests/data/valid_get_security_group.json'))
+ get_networks.return_value = None
with mock.patch('requests.get', get):
with mock.patch('gstack.controllers.get_item_with_name', get_networks):