libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject [1/7] Add a new driver, tests and documentation for CloudSigma API v2.0.
Date Wed, 29 Jan 2014 16:00:55 GMT
Updated Branches:
  refs/heads/trunk 903e769d3 -> 23c3b44f1


http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_all_stopped.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_all_stopped.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_all_stopped.json
new file mode 100644
index 0000000..24eb4b2
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_all_stopped.json
@@ -0,0 +1,104 @@
+{
+    "meta": {
+        "limit": 20,
+        "offset": 0,
+        "total_count": 2
+    },
+    "objects": [
+        {
+            "context": true,
+            "cpu": 1000,
+            "cpu_model": null,
+            "cpus_instead_of_cores": false,
+            "drives": [],
+            "enable_numa": false,
+            "hv_relaxed": false,
+            "hv_tsc": false,
+            "mem": 1073741824,
+            "meta": {
+                "description": "test description 2",
+                "ssh_public_key": ""
+            },
+            "name": "test no drives",
+            "nics": [
+                {
+                    "boot_order": null,
+                    "firewall_policy": null,
+                    "ip_v4_conf": {
+                        "conf": "dhcp",
+                        "ip": null
+                    },
+                    "ip_v6_conf": null,
+                    "mac": "22:98:ce:04:50:df",
+                    "model": "virtio",
+                    "runtime": null,
+                    "vlan": null
+                }
+            ],
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "requirements": [],
+            "resource_uri": "/api/2.0/servers/9de75ed6-fd33-45e2-963f-d405f31fd911/",
+            "runtime": null,
+            "smp": 1,
+            "status": "stopped",
+            "tags": [],
+            "uuid": "9de75ed6-fd33-45e2-963f-d405f31fd911",
+            "vnc_password": "bar"
+        },
+        {
+            "context": true,
+            "cpu": 2000,
+            "cpu_model": null,
+            "cpus_instead_of_cores": false,
+            "drives": [
+                {
+                    "boot_order": 1,
+                    "dev_channel": "0:0",
+                    "device": "ide",
+                    "drive": {
+                        "resource_uri": "/api/2.0/drives/3f74acec-ba3c-4efd-ab9e-5d95a4c5fca9/",
+                        "uuid": "3f74acec-ba3c-4efd-ab9e-5d95a4c5fca9"
+                    }
+                }
+            ],
+            "enable_numa": false,
+            "hv_relaxed": false,
+            "hv_tsc": false,
+            "mem": 2147483648,
+            "meta": {
+                "description": "test1"
+            },
+            "name": "test-1",
+            "nics": [
+                {
+                    "boot_order": null,
+                    "firewall_policy": null,
+                    "ip_v4_conf": {
+                        "conf": "dhcp",
+                        "ip": null
+                    },
+                    "ip_v6_conf": null,
+                    "mac": "22:22:4e:1e:e0:7e",
+                    "model": "virtio",
+                    "runtime": null,
+                    "vlan": null
+                }
+            ],
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "requirements": [],
+            "resource_uri": "/api/2.0/servers/9414bbeb-e908-4e55-ae3f-2eb61adc50d8/",
+            "runtime": null,
+            "smp": 1,
+            "status": "stopped",
+            "tags": [],
+            "uuid": "9414bbeb-e908-4e55-ae3f-2eb61adc50d8",
+            "vnc_password": "foo"
+        }
+    ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_mixed_state.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_mixed_state.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_mixed_state.json
new file mode 100644
index 0000000..b89ec2b
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_detail_mixed_state.json
@@ -0,0 +1,162 @@
+{
+    "meta": {
+        "limit": 20,
+        "offset": 0,
+        "total_count": 2
+    },
+    "objects": [
+        {
+            "context": true,
+            "cpu": 1000,
+            "cpu_model": null,
+            "cpus_instead_of_cores": false,
+            "drives": [],
+            "enable_numa": false,
+            "hv_relaxed": false,
+            "hv_tsc": false,
+            "mem": 1073741824,
+            "meta": {
+                "description": "test description 2",
+                "ssh_public_key": ""
+            },
+            "name": "test no drives",
+            "nics": [
+                {
+                    "boot_order": null,
+                    "firewall_policy": null,
+                    "ip_v4_conf": {
+                        "conf": "dhcp",
+                        "ip": null
+                    },
+                    "ip_v6_conf": null,
+                    "mac": "22:98:ce:04:50:df",
+                    "model": "virtio",
+                    "runtime": {
+                        "interface_type": "public",
+                        "io": {
+                            "bytes_recv": "1323",
+                            "bytes_sent": "21535",
+                            "packets_recv": "3",
+                            "packets_sent": "278"
+                        },
+                        "ip_v4": {
+                            "resource_uri": "/api/2.0/ips/185.12.5.181/",
+                            "uuid": "185.12.5.181"
+                        },
+                        "ip_v6": null
+                    },
+                    "vlan": null
+                },
+                {
+                    "boot_order": null,
+                    "firewall_policy": null,
+                    "ip_v4_conf": {
+                        "conf": "dhcp",
+                        "ip": null
+                    },
+                    "ip_v6_conf": null,
+                    "mac": "22:2c:03:99:32:be",
+                    "model": "virtio",
+                    "runtime": {
+                        "interface_type": "public",
+                        "io": {
+                            "bytes_recv": "0",
+                            "bytes_sent": "0",
+                            "packets_recv": "0",
+                            "packets_sent": "0"
+                        },
+                        "ip_v4": {
+                            "resource_uri": "/api/2.0/ips/178.22.68.55/",
+                            "uuid": "178.22.68.55"
+                        },
+                        "ip_v6": null
+                    },
+                    "vlan": null
+                }
+            ],
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "requirements": [],
+            "resource_uri": "/api/2.0/servers/9de75ed6-fd33-45e2-963f-d405f31fd911/",
+            "runtime": {
+                "active_since": "2013-11-05T10:15:42+00:00",
+                "nics": [
+                    {
+                        "interface_type": "public",
+                        "io": {
+                            "bytes_recv": "1323",
+                            "bytes_sent": "21535",
+                            "packets_recv": "3",
+                            "packets_sent": "278"
+                        },
+                        "ip_v4": {
+                            "resource_uri": "/api/2.0/ips/185.12.5.181/",
+                            "uuid": "185.12.5.181"
+                        },
+                        "ip_v6": null,
+                        "mac": "22:98:ce:04:50:df"
+                    }
+                ]
+            },
+            "smp": 1,
+            "status": "running",
+            "tags": [],
+            "uuid": "9de75ed6-fd33-45e2-963f-d405f31fd911",
+            "vnc_password": "foo"
+        },
+        {
+            "context": true,
+            "cpu": 2000,
+            "cpu_model": null,
+            "cpus_instead_of_cores": false,
+            "drives": [
+                {
+                    "boot_order": 1,
+                    "dev_channel": "0:0",
+                    "device": "ide",
+                    "drive": {
+                        "resource_uri": "/api/2.0/drives/3f74acec-ba3c-4efd-ab9e-5d95a4c5fca9/",
+                        "uuid": "3f74acec-ba3c-4efd-ab9e-5d95a4c5fca9"
+                    }
+                }
+            ],
+            "enable_numa": false,
+            "hv_relaxed": false,
+            "hv_tsc": false,
+            "mem": 2147483648,
+            "meta": {
+                "description": "test1"
+            },
+            "name": "test-1",
+            "nics": [
+                {
+                    "boot_order": null,
+                    "firewall_policy": null,
+                    "ip_v4_conf": {
+                        "conf": "dhcp",
+                        "ip": null
+                    },
+                    "ip_v6_conf": null,
+                    "mac": "22:22:4e:1e:e0:7e",
+                    "model": "virtio",
+                    "runtime": null,
+                    "vlan": null
+                }
+            ],
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "requirements": [],
+            "resource_uri": "/api/2.0/servers/9414bbeb-e908-4e55-ae3f-2eb61adc50d8/",
+            "runtime": null,
+            "smp": 1,
+            "status": "stopped",
+            "tags": [],
+            "uuid": "9414bbeb-e908-4e55-ae3f-2eb61adc50d8",
+            "vnc_password": "bar"
+        }
+    ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_open_vnc.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_open_vnc.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_open_vnc.json
new file mode 100644
index 0000000..a04b183
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/servers_open_vnc.json
@@ -0,0 +1,6 @@
+{
+    "action": "open_vnc",
+    "result": "success",
+    "uuid": "2e64e5e4-f31d-471a-ac1b-1ae079652e40",
+    "vnc_url": "vnc://direct.lvs.cloudsigma.com:41111"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/start_already_started.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/start_already_started.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/start_already_started.json
new file mode 100644
index 0000000..e612d8e
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/start_already_started.json
@@ -0,0 +1 @@
+[{"error_point": null, "error_type": "permission", "error_message": "Cannot start guest in state \"started\". Guest should be in state \"stopped\""}]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/start_success.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/start_success.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/start_success.json
new file mode 100644
index 0000000..1e60e5d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/start_success.json
@@ -0,0 +1 @@
+{"action": "start", "result": "success", "uuid": "9414bbeb-e908-4e55-ae3f-2eb61adc50d8"}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_already_stopped.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_already_stopped.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_already_stopped.json
new file mode 100644
index 0000000..52abcfc
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_already_stopped.json
@@ -0,0 +1 @@
+[{"error_point": null, "error_type": "permission", "error_message": "Cannot stop guest in state \"stopped\". Guest should be in state \"['started', 'running_legacy']\""}]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_success.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_success.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_success.json
new file mode 100644
index 0000000..e35b107
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/stop_success.json
@@ -0,0 +1 @@
+{"action": "stop", "result": "success", "uuid": "9414bbeb-e908-4e55-ae3f-2eb61adc50d8"}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/subscriptions.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/subscriptions.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/subscriptions.json
new file mode 100644
index 0000000..f57b6ef
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/subscriptions.json
@@ -0,0 +1,105 @@
+{
+    "meta": {
+        "limit": 20,
+        "offset": 0,
+        "total_count": 5
+    },
+    "objects": [
+        {
+            "amount": "1",
+            "auto_renew": true,
+            "descendants": [],
+            "discount_amount": null,
+            "discount_percent": null,
+            "end_time": "2014-02-20T11:12:34.930946+00:00",
+            "id": "7272",
+            "last_notification": null,
+            "period": "345 days, 0:00:00",
+            "price": "0E-20",
+            "remaining": "1",
+            "resource": "vlan",
+            "resource_uri": "/api/2.0/subscriptions/7272/",
+            "start_time": "2013-03-12T11:12:34.930946+00:00",
+            "status": "active",
+            "subscribed_object": "96537817-f4b6-496b-a861-e74192d3ccb0",
+            "uuid": "509f8e27-1e64-49bb-aa5a-baec074b0210"
+        },
+        {
+            "amount": "1",
+            "auto_renew": true,
+            "descendants": [],
+            "discount_amount": null,
+            "discount_percent": null,
+            "end_time": "2014-02-20T11:12:41.837474+00:00",
+            "id": "7273",
+            "last_notification": null,
+            "period": "345 days, 0:00:00",
+            "price": "0E-20",
+            "remaining": "1",
+            "resource": "ip",
+            "resource_uri": "/api/2.0/subscriptions/7273/",
+            "start_time": "2013-03-12T11:12:41.837474+00:00",
+            "status": "active",
+            "subscribed_object": "185.12.6.183",
+            "uuid": "c2423c1a-8768-462c-bdc3-4ca09c1e650b"
+        },
+        {
+            "amount": "17179869184",
+            "auto_renew": true,
+            "descendants": [],
+            "discount_amount": null,
+            "discount_percent": null,
+            "end_time": "2014-02-20T14:04:14.142181+00:00",
+            "id": "3985",
+            "last_notification": null,
+            "period": "365 days, 0:00:00",
+            "price": "0E-20",
+            "remaining": "17179869184",
+            "resource": "mem",
+            "resource_uri": "/api/2.0/subscriptions/3985/",
+            "start_time": "2013-02-20T14:04:14.142181+00:00",
+            "status": "active",
+            "subscribed_object": null,
+            "uuid": "9bb117d3-4bc5-4e2d-a907-b20abd48eaf9"
+        },
+        {
+            "amount": "8000",
+            "auto_renew": true,
+            "descendants": [],
+            "discount_amount": null,
+            "discount_percent": null,
+            "end_time": "2014-02-20T14:04:29.040258+00:00",
+            "id": "3986",
+            "last_notification": null,
+            "period": "365 days, 0:00:00",
+            "price": "0E-20",
+            "remaining": "8000",
+            "resource": "cpu",
+            "resource_uri": "/api/2.0/subscriptions/3986/",
+            "start_time": "2013-02-20T14:04:29.040258+00:00",
+            "status": "active",
+            "subscribed_object": null,
+            "uuid": "a265c47f-1a00-4095-acfc-2193622bfbd8"
+        },
+        {
+            "amount": "32212254720",
+            "auto_renew": true,
+            "descendants": [],
+            "discount_amount": null,
+            "discount_percent": null,
+            "end_time": "2014-02-20T14:04:44.088984+00:00",
+            "id": "3987",
+            "last_notification": null,
+            "period": "365 days, 0:00:00",
+            "price": "0E-20",
+            "remaining": "32212254720",
+            "resource": "dssd",
+            "resource_uri": "/api/2.0/subscriptions/3987/",
+            "start_time": "2013-02-20T14:04:44.088984+00:00",
+            "status": "active",
+            "subscribed_object": null,
+            "uuid": "8965ff95-4924-40a9-b923-a58615149732"
+        }
+    ],
+    "price": "0E-20"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create.json
new file mode 100644
index 0000000..8b4d843
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create.json
@@ -0,0 +1,15 @@
+{
+    "objects": [
+        {
+            "meta": {},
+            "name": "test tag 3",
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "resource_uri": "/api/2.0/tags/c0008127-6dbf-4cf3-85f5-203f4c3967fa/",
+            "resources": [],
+            "uuid": "c0008127-6dbf-4cf3-85f5-203f4c3967fa"
+        }
+    ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create_with_resources.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create_with_resources.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create_with_resources.json
new file mode 100644
index 0000000..d2e1f2f
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_create_with_resources.json
@@ -0,0 +1,25 @@
+{
+    "objects": [
+        {
+            "meta": {},
+            "name": "test tag 3",
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "resource_uri": "/api/2.0/tags/c0008127-6dbf-4cf3-85f5-203f4c3967fa/",
+            "resources": [
+              {
+                    "owner": {
+                        "resource_uri": "/api/2.0/user/5b4a69a3-8e78-4c45-a8ba-8b13f0895e23/",
+                        "uuid": "5b4a69a3-8e78-4c45-a8ba-8b13f0895e23"
+                    },
+                    "res_type": "vlans",
+                    "resource_uri": "/api/2.0/vlans/96537817-f4b6-496b-a861-e74192d3ccb0/",
+                    "uuid": "1"
+              }
+            ],
+            "uuid": "c0008127-6dbf-4cf3-85f5-203f4c3967fa"
+        }
+    ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_detail.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_detail.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_detail.json
new file mode 100644
index 0000000..c54dd22
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_detail.json
@@ -0,0 +1,31 @@
+{
+    "meta": {
+        "limit": 20,
+        "offset": 0,
+        "total_count": 2
+    },
+    "objects": [
+        {
+            "meta": {},
+            "name": "test tag 2",
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "resource_uri": "/api/2.0/tags/a010ec41-2ead-4630-a1d0-237fa77e4d4d/",
+            "resources": [],
+            "uuid": "a010ec41-2ead-4630-a1d0-237fa77e4d4d"
+        },
+        {
+            "meta": {},
+            "name": "test tag 1",
+            "owner": {
+                "resource_uri": "/api/2.0/user/69fcfc03-d635-4f99-a8b3-e1b73637cb5d/",
+                "uuid": "69fcfc03-d635-4f99-a8b3-e1b73637cb5d"
+            },
+            "resource_uri": "/api/2.0/tags/e60bb2d2-08d4-4255-adac-5faf87efcdd2/",
+            "resources": [],
+            "uuid": "e60bb2d2-08d4-4255-adac-5faf87efcdd2"
+        }
+    ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_get.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_get.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_get.json
new file mode 100644
index 0000000..cc794c2
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_get.json
@@ -0,0 +1,11 @@
+{
+    "meta": {},
+    "name": "test tag 2",
+    "owner": {
+        "resource_uri": "/api/2.0/user/5b4a69a3-8e78-4c45-a8ba-8b13f0895e23/",
+        "uuid": "5b4a69a3-8e78-4c45-a8ba-8b13f0895e23"
+    },
+    "resource_uri": "/api/2.0/tags/a010ec41-2ead-4630-a1d0-237fa77e4d4d/",
+    "resources": [],
+    "uuid": "a010ec41-2ead-4630-a1d0-237fa77e4d4d"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_update.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_update.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_update.json
new file mode 100644
index 0000000..28e7be6
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/tags_update.json
@@ -0,0 +1,30 @@
+{
+    "meta": {},
+    "name": "test tag 3",
+    "owner": {
+        "resource_uri": "/api/2.0/user/5b4a69a3-8e78-4c45-a8ba-8b13f0895e23/",
+        "uuid": "5b4a69a3-8e78-4c45-a8ba-8b13f0895e23"
+    },
+    "resource_uri": "/api/2.0/tags/900ac9c6-2f98-48a4-b406-5494b4ea4663/",
+    "resources": [
+        {
+            "owner": {
+                "resource_uri": "/api/2.0/user/5b4a69a3-8e78-4c45-a8ba-8b13f0895e23/",
+                "uuid": "5b4a69a3-8e78-4c45-a8ba-8b13f0895e23"
+            },
+            "res_type": "servers",
+            "resource_uri": "/api/2.0/servers/79f7853b-04bd-44f5-a2c2-fa56f6861994/",
+            "uuid": "79f7853b-04bd-44f5-a2c2-fa56f6861994"
+        },
+        {
+            "owner": {
+                "resource_uri": "/api/2.0/user/5b4a69a3-8e78-4c45-a8ba-8b13f0895e23/",
+                "uuid": "5b4a69a3-8e78-4c45-a8ba-8b13f0895e23"
+            },
+            "res_type": "drives",
+            "resource_uri": "/api/2.0/drives/8c48e0bd-e17b-49ca-8926-654107d2b7e7/",
+            "uuid": "8c48e0bd-e17b-49ca-8926-654107d2b7e7"
+        }
+    ],
+    "uuid": "900ac9c6-2f98-48a4-b406-5494b4ea4663"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/fixtures/cloudsigma_2_0/unknown_error.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/cloudsigma_2_0/unknown_error.json b/libcloud/test/compute/fixtures/cloudsigma_2_0/unknown_error.json
new file mode 100644
index 0000000..8543d1c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/cloudsigma_2_0/unknown_error.json
@@ -0,0 +1 @@
+[{"error_point": null, "error_type": "backend", "error_message": "unknown error"}]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/test_cloudsigma.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_cloudsigma.py b/libcloud/test/compute/test_cloudsigma.py
deleted file mode 100644
index ecbe63a..0000000
--- a/libcloud/test/compute/test_cloudsigma.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import unittest
-from libcloud.utils.py3 import httplib
-
-from libcloud.compute.base import Node
-from libcloud.compute.drivers.cloudsigma import CloudSigmaZrhNodeDriver
-from libcloud.utils.misc import str2dicts, str2list, dict2str
-
-from libcloud.test import MockHttp               # pylint: disable-msg=E0611
-from libcloud.test.compute import TestCaseMixin  # pylint: disable-msg=E0611
-from libcloud.test.file_fixtures import ComputeFileFixtures  # pylint: disable-msg=E0611
-
-
-class CloudSigmaTestCase(unittest.TestCase, TestCaseMixin):
-
-    def setUp(self):
-        CloudSigmaZrhNodeDriver.connectionCls.conn_classes = (None,
-                                                              CloudSigmaHttp)
-        self.driver = CloudSigmaZrhNodeDriver('foo', 'bar')
-
-    def test_list_nodes(self):
-        nodes = self.driver.list_nodes()
-        self.assertTrue(isinstance(nodes, list))
-        self.assertEqual(len(nodes), 1)
-
-        node = nodes[0]
-        self.assertEqual(node.public_ips[0], "1.2.3.4")
-        self.assertEqual(node.extra['smp'], 1)
-        self.assertEqual(node.extra['cpu'], 1100)
-        self.assertEqual(node.extra['mem'], 640)
-
-    def test_list_sizes(self):
-        images = self.driver.list_sizes()
-        self.assertEqual(len(images), 9)
-
-    def test_list_images(self):
-        sizes = self.driver.list_images()
-        self.assertEqual(len(sizes), 10)
-
-    def test_list_locations_response(self):
-        pass
-
-    def test_start_node(self):
-        nodes = self.driver.list_nodes()
-        node = nodes[0]
-        self.assertTrue(self.driver.ex_start_node(node))
-
-    def test_shutdown_node(self):
-        nodes = self.driver.list_nodes()
-        node = nodes[0]
-        self.assertTrue(self.driver.ex_stop_node(node))
-        self.assertTrue(self.driver.ex_shutdown_node(node))
-
-    def test_reboot_node(self):
-        node = self.driver.list_nodes()[0]
-        self.assertTrue(self.driver.reboot_node(node))
-
-    def test_destroy_node(self):
-        node = self.driver.list_nodes()[0]
-        self.assertTrue(self.driver.destroy_node(node))
-        self.driver.list_nodes()
-
-    def test_create_node(self):
-        size = self.driver.list_sizes()[0]
-        image = self.driver.list_images()[0]
-        node = self.driver.create_node(
-            name="cloudsigma node", image=image, size=size)
-        self.assertTrue(isinstance(node, Node))
-
-    def test_ex_static_ip_list(self):
-        ips = self.driver.ex_static_ip_list()
-        self.assertEqual(len(ips), 3)
-
-    def test_ex_static_ip_create(self):
-        result = self.driver.ex_static_ip_create()
-        self.assertEqual(len(result), 2)
-        self.assertEqual(len(list(result[0].keys())), 6)
-        self.assertEqual(len(list(result[1].keys())), 6)
-
-    def test_ex_static_ip_destroy(self):
-        result = self.driver.ex_static_ip_destroy('1.2.3.4')
-        self.assertTrue(result)
-
-    def test_ex_drives_list(self):
-        result = self.driver.ex_drives_list()
-        self.assertEqual(len(result), 2)
-
-    def test_ex_drive_destroy(self):
-        result = self.driver.ex_drive_destroy(
-            # @@TR: this should be soft-coded:
-            'd18119ce_7afa_474a_9242_e0384b160220')
-        self.assertTrue(result)
-
-    def test_ex_set_node_configuration(self):
-        node = self.driver.list_nodes()[0]
-        result = self.driver.ex_set_node_configuration(node, **{'smp': 2})
-        self.assertTrue(result)
-
-    def test_str2dicts(self):
-        string = 'mem 1024\ncpu 2200\n\nmem2048\cpu 1100'
-        result = str2dicts(string)
-        self.assertEqual(len(result), 2)
-
-    def test_str2list(self):
-        string = 'ip 1.2.3.4\nip 1.2.3.5\nip 1.2.3.6'
-        result = str2list(string)
-        self.assertEqual(len(result), 3)
-        self.assertEqual(result[0], '1.2.3.4')
-        self.assertEqual(result[1], '1.2.3.5')
-        self.assertEqual(result[2], '1.2.3.6')
-
-    def test_dict2str(self):
-        d = {'smp': 5, 'cpu': 2200, 'mem': 1024}
-        result = dict2str(d)
-        self.assertTrue(len(result) > 0)
-        self.assertTrue(result.find('smp 5') >= 0)
-        self.assertTrue(result.find('cpu 2200') >= 0)
-        self.assertTrue(result.find('mem 1024') >= 0)
-
-
-class CloudSigmaHttp(MockHttp):
-    fixtures = ComputeFileFixtures('cloudsigma')
-
-    def _drives_standard_info(self, method, url, body, headers):
-        body = self.fixtures.load('drives_standard_info.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_start(
-            self, method, url, body, headers):
-
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_stop(
-            self, method, url, body, headers):
-
-        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_destroy(
-            self, method, url, body, headers):
-
-        return (httplib.NO_CONTENT,
-                body, {}, httplib.responses[httplib.NO_CONTENT])
-
-    def _drives_d18119ce_7afa_474a_9242_e0384b160220_clone(
-            self, method, url, body, headers):
-
-        body = self.fixtures.load('drives_clone.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _drives_a814def5_1789_49a0_bf88_7abe7bb1682a_info(
-            self, method, url, body, headers):
-
-        body = self.fixtures.load('drives_single_info.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _drives_info(self, method, url, body, headers):
-        body = self.fixtures.load('drives_info.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_create(self, method, url, body, headers):
-        body = self.fixtures.load('servers_create.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_info(self, method, url, body, headers):
-        body = self.fixtures.load('servers_info.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _resources_ip_list(self, method, url, body, headers):
-        body = self.fixtures.load('resources_ip_list.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _resources_ip_create(self, method, url, body, headers):
-        body = self.fixtures.load('resources_ip_create.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-    def _resources_ip_1_2_3_4_destroy(self, method, url, body, headers):
-        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
-
-    def _drives_d18119ce_7afa_474a_9242_e0384b160220_destroy(
-            self, method, url, body, headers):
-
-        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
-
-    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_set(
-            self, method, url, body, headers):
-
-        body = self.fixtures.load('servers_set.txt')
-        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
-
-if __name__ == '__main__':
-    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/test_cloudsigma_v1_0.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_cloudsigma_v1_0.py b/libcloud/test/compute/test_cloudsigma_v1_0.py
new file mode 100644
index 0000000..d8fb310
--- /dev/null
+++ b/libcloud/test/compute/test_cloudsigma_v1_0.py
@@ -0,0 +1,223 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import unittest
+from libcloud.utils.py3 import httplib
+
+from libcloud.compute.base import Node
+from libcloud.compute.drivers.cloudsigma import CloudSigmaNodeDriver
+from libcloud.compute.drivers.cloudsigma import CloudSigmaZrhNodeDriver
+from libcloud.utils.misc import str2dicts, str2list, dict2str
+
+from libcloud.test import MockHttp
+from libcloud.test.file_fixtures import ComputeFileFixtures
+
+
+class CloudSigmaAPI10BaseTestCase(object):
+    should_list_locations = False
+
+    driver_klass = CloudSigmaZrhNodeDriver
+    driver_kwargs = {}
+
+    def setUp(self):
+        self.driver = self.driver_klass(*self.driver_args,
+                                        **self.driver_kwargs)
+
+        self.driver.connectionCls.conn_classes = (None,
+                                                  CloudSigmaHttp)
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes()
+        self.assertTrue(isinstance(nodes, list))
+        self.assertEqual(len(nodes), 1)
+
+        node = nodes[0]
+        self.assertEqual(node.public_ips[0], "1.2.3.4")
+        self.assertEqual(node.extra['smp'], 1)
+        self.assertEqual(node.extra['cpu'], 1100)
+        self.assertEqual(node.extra['mem'], 640)
+
+    def test_list_sizes(self):
+        images = self.driver.list_sizes()
+        self.assertEqual(len(images), 9)
+
+    def test_list_images(self):
+        sizes = self.driver.list_images()
+        self.assertEqual(len(sizes), 10)
+
+    def test_start_node(self):
+        nodes = self.driver.list_nodes()
+        node = nodes[0]
+        self.assertTrue(self.driver.ex_start_node(node))
+
+    def test_shutdown_node(self):
+        nodes = self.driver.list_nodes()
+        node = nodes[0]
+        self.assertTrue(self.driver.ex_stop_node(node))
+        self.assertTrue(self.driver.ex_shutdown_node(node))
+
+    def test_reboot_node(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.reboot_node(node))
+
+    def test_destroy_node(self):
+        node = self.driver.list_nodes()[0]
+        self.assertTrue(self.driver.destroy_node(node))
+        self.driver.list_nodes()
+
+    def test_create_node(self):
+        size = self.driver.list_sizes()[0]
+        image = self.driver.list_images()[0]
+        node = self.driver.create_node(
+            name="cloudsigma node", image=image, size=size)
+        self.assertTrue(isinstance(node, Node))
+
+    def test_ex_static_ip_list(self):
+        ips = self.driver.ex_static_ip_list()
+        self.assertEqual(len(ips), 3)
+
+    def test_ex_static_ip_create(self):
+        result = self.driver.ex_static_ip_create()
+        self.assertEqual(len(result), 2)
+        self.assertEqual(len(list(result[0].keys())), 6)
+        self.assertEqual(len(list(result[1].keys())), 6)
+
+    def test_ex_static_ip_destroy(self):
+        result = self.driver.ex_static_ip_destroy('1.2.3.4')
+        self.assertTrue(result)
+
+    def test_ex_drives_list(self):
+        result = self.driver.ex_drives_list()
+        self.assertEqual(len(result), 2)
+
+    def test_ex_drive_destroy(self):
+        result = self.driver.ex_drive_destroy(
+            # @@TR: this should be soft-coded:
+            'd18119ce_7afa_474a_9242_e0384b160220')
+        self.assertTrue(result)
+
+    def test_ex_set_node_configuration(self):
+        node = self.driver.list_nodes()[0]
+        result = self.driver.ex_set_node_configuration(node, **{'smp': 2})
+        self.assertTrue(result)
+
+    def test_str2dicts(self):
+        string = 'mem 1024\ncpu 2200\n\nmem2048\cpu 1100'
+        result = str2dicts(string)
+        self.assertEqual(len(result), 2)
+
+    def test_str2list(self):
+        string = 'ip 1.2.3.4\nip 1.2.3.5\nip 1.2.3.6'
+        result = str2list(string)
+        self.assertEqual(len(result), 3)
+        self.assertEqual(result[0], '1.2.3.4')
+        self.assertEqual(result[1], '1.2.3.5')
+        self.assertEqual(result[2], '1.2.3.6')
+
+    def test_dict2str(self):
+        d = {'smp': 5, 'cpu': 2200, 'mem': 1024}
+        result = dict2str(d)
+        self.assertTrue(len(result) > 0)
+        self.assertTrue(result.find('smp 5') >= 0)
+        self.assertTrue(result.find('cpu 2200') >= 0)
+        self.assertTrue(result.find('mem 1024') >= 0)
+
+
+class CloudSigmaAPI10DirectTestCase(CloudSigmaAPI10BaseTestCase,
+                                    unittest.TestCase):
+    driver_klass = CloudSigmaZrhNodeDriver
+    driver_args = ('foo', 'bar')
+    driver_kwargs = {}
+
+
+class CloudSigmaAPI10IndiretTestCase(CloudSigmaAPI10BaseTestCase,
+                                     unittest.TestCase):
+    driver_klass = CloudSigmaNodeDriver
+    driver_args = ('foo', 'bar')
+    driver_kwargs = {'api_version': '1.0'}
+
+
+class CloudSigmaHttp(MockHttp):
+    fixtures = ComputeFileFixtures('cloudsigma')
+
+    def _drives_standard_info(self, method, url, body, headers):
+        body = self.fixtures.load('drives_standard_info.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_start(
+            self, method, url, body, headers):
+
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_stop(
+            self, method, url, body, headers):
+
+        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_destroy(
+            self, method, url, body, headers):
+
+        return (httplib.NO_CONTENT,
+                body, {}, httplib.responses[httplib.NO_CONTENT])
+
+    def _drives_d18119ce_7afa_474a_9242_e0384b160220_clone(
+            self, method, url, body, headers):
+
+        body = self.fixtures.load('drives_clone.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _drives_a814def5_1789_49a0_bf88_7abe7bb1682a_info(
+            self, method, url, body, headers):
+
+        body = self.fixtures.load('drives_single_info.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _drives_info(self, method, url, body, headers):
+        body = self.fixtures.load('drives_info.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_create(self, method, url, body, headers):
+        body = self.fixtures.load('servers_create.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_info(self, method, url, body, headers):
+        body = self.fixtures.load('servers_info.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _resources_ip_list(self, method, url, body, headers):
+        body = self.fixtures.load('resources_ip_list.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _resources_ip_create(self, method, url, body, headers):
+        body = self.fixtures.load('resources_ip_create.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _resources_ip_1_2_3_4_destroy(self, method, url, body, headers):
+        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
+
+    def _drives_d18119ce_7afa_474a_9242_e0384b160220_destroy(
+            self, method, url, body, headers):
+
+        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK])
+
+    def _servers_62fe7cde_4fb9_4c63_bd8c_e757930066a0_set(
+            self, method, url, body, headers):
+
+        body = self.fixtures.load('servers_set.txt')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d40ecd3/libcloud/test/compute/test_cloudsigma_v2_0.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_cloudsigma_v2_0.py b/libcloud/test/compute/test_cloudsigma_v2_0.py
new file mode 100644
index 0000000..9e6690c
--- /dev/null
+++ b/libcloud/test/compute/test_cloudsigma_v2_0.py
@@ -0,0 +1,573 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+from libcloud.utils.py3 import httplib
+
+from libcloud.common.types import InvalidCredsError
+from libcloud.compute.drivers.cloudsigma import CloudSigmaNodeDriver
+from libcloud.compute.drivers.cloudsigma import CloudSigma_2_0_NodeDriver
+from libcloud.compute.drivers.cloudsigma import CloudSigmaError
+from libcloud.compute.types import NodeState
+
+from libcloud.test import unittest
+from libcloud.test import MockHttpTestCase
+from libcloud.test.file_fixtures import ComputeFileFixtures
+
+
+class CloudSigmaAPI20BaseTestCase(object):
+    def setUp(self):
+        self.driver_klass.connectionCls.conn_classes = \
+            (CloudSigmaMockHttp, CloudSigmaMockHttp)
+
+        CloudSigmaMockHttp.type = None
+        CloudSigmaMockHttp.use_param = 'do'
+
+        self.driver = self.driver_klass(*self.driver_args,
+                                        **self.driver_kwargs)
+        self.driver.DRIVE_TRANSITION_SLEEP_INTERVAL = 0.1
+        self.driver.DRIVE_TRANSITION_TIMEOUT = 1
+        self.node = self.driver.list_nodes()[0]
+
+    def test_invalid_api_versions(self):
+        expected_msg = 'Unsupported API version: invalid'
+        self.assertRaisesRegexp(NotImplementedError, expected_msg,
+                                CloudSigmaNodeDriver, 'username', 'password',
+                                api_version='invalid')
+
+    def test_invalid_credentials(self):
+        CloudSigmaMockHttp.type = 'INVALID_CREDS'
+        self.assertRaises(InvalidCredsError, self.driver.list_nodes)
+
+    def test_invalid_region(self):
+        expected_msg = 'Invalid region:'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                CloudSigma_2_0_NodeDriver, 'foo', 'bar',
+                                region='invalid')
+
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+
+        size = sizes[0]
+        self.assertEqual(size.id, 'micro-regular')
+
+    def test_list_images(self):
+        images = self.driver.list_images()
+
+        image = images[0]
+        self.assertEqual(image.name, 'ubuntu-10.04-toMP')
+        self.assertEqual(image.extra['image_type'], 'preinst')
+        self.assertEqual(image.extra['media'], 'disk')
+        self.assertEqual(image.extra['os'], 'linux')
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes()
+
+        node = nodes[0]
+        self.assertEqual(len(nodes), 2)
+        self.assertEqual(node.id, '9de75ed6-fd33-45e2-963f-d405f31fd911')
+        self.assertEqual(node.name, 'test no drives')
+        self.assertEqual(node.state, NodeState.RUNNING)
+        self.assertEqual(node.public_ips, ['185.12.5.181', '178.22.68.55'])
+        self.assertEqual(node.private_ips, [])
+
+    def test_create_node(self):
+        image = self.driver.list_images()[0]
+        size = self.driver.list_sizes()[0]
+        metadata = {'foo': 'bar'}
+
+        node = self.driver.create_node(name='test node', size=size, image=image,
+                                       ex_metadata=metadata)
+        self.assertEqual(node.name, 'test node')
+
+    def test_destroy_node(self):
+        status = self.driver.destroy_node(node=self.node)
+        self.assertTrue(status)
+
+    def test_ex_start_node(self):
+        status = self.driver.ex_start_node(node=self.node)
+        self.assertTrue(status)
+
+    def test_ex_start_node_avoid_mode(self):
+        CloudSigmaMockHttp.type = 'AVOID_MODE'
+        ex_avoid = ['1', '2']
+        status = self.driver.ex_start_node(node=self.node,
+                                           ex_avoid=ex_avoid)
+        self.assertTrue(status)
+
+    def test_ex_start_node_already_started(self):
+        CloudSigmaMockHttp.type = 'ALREADY_STARTED'
+
+        expected_msg = 'Cannot start guest in state "started". Guest should ' \
+                       'be in state "stopped'
+
+        self.assertRaisesRegexp(CloudSigmaError, expected_msg,
+                                self.driver.ex_start_node, node=self.node)
+
+    def test_ex_stop_node(self):
+        status = self.driver.ex_stop_node(node=self.node)
+        self.assertTrue(status)
+
+    def test_ex_stop_node_already_stopped(self):
+        CloudSigmaMockHttp.type = 'ALREADY_STOPPED'
+
+        expected_msg = 'Cannot stop guest in state "stopped"'
+        self.assertRaisesRegexp(CloudSigmaError, expected_msg,
+                                self.driver.ex_stop_node, node=self.node)
+
+    def test_ex_clone_node(self):
+        node_to_clone = self.driver.list_nodes()[0]
+
+        cloned_node = self.driver.ex_clone_node(node=node_to_clone,
+                                                name='test cloned node')
+        self.assertEqual(cloned_node.name, 'test cloned node')
+
+    def test_ex_open_vnc_tunnel(self):
+        node = self.driver.list_nodes()[0]
+        vnc_url = self.driver.ex_open_vnc_tunnel(node=node)
+        self.assertEqual(vnc_url, 'vnc://direct.lvs.cloudsigma.com:41111')
+
+    def test_ex_close_vnc_tunnel(self):
+        node = self.driver.list_nodes()[0]
+        status = self.driver.ex_close_vnc_tunnel(node=node)
+        self.assertTrue(status)
+
+    def test_ex_list_drives(self):
+        drives = self.driver.ex_list_drives()
+
+        drive = drives[0]
+        self.assertEqual(drive.name, 'test node 2-drive')
+        self.assertEqual(drive.size, 13958643712)
+        self.assertEqual(drive.media, 'disk')
+        self.assertEqual(drive.status, 'unmounted')
+
+    def test_ex_create_drive(self):
+        CloudSigmaMockHttp.type = 'CREATE'
+
+        name = 'test drive 5'
+        size = 2000 * 1024 * 1024
+
+        drive = self.driver.ex_create_drive(name=name, size=size, media='disk')
+        self.assertEqual(drive.name, 'test drive 5')
+        self.assertEqual(drive.media, 'disk')
+
+    def test_ex_clone_drive(self):
+        drive = self.driver.ex_list_drives()[0]
+        cloned_drive = self.driver.ex_clone_drive(drive=drive,
+                                                  name='cloned drive')
+
+        self.assertEqual(cloned_drive.name, 'cloned drive')
+
+    def test_ex_resize_drive(self):
+        drive = self.driver.ex_list_drives()[0]
+
+        size = 1111 * 1024 * 1024
+
+        resized_drive = self.driver.ex_resize_drive(drive=drive, size=size)
+        self.assertEqual(resized_drive.name, 'test drive 5')
+        self.assertEqual(resized_drive.media, 'disk')
+        self.assertEqual(resized_drive.size, size)
+
+    def test_ex_list_firewall_policies(self):
+        policies = self.driver.ex_list_firewall_policies()
+
+        policy = policies[1]
+        rule = policy.rules[0]
+        self.assertEqual(policy.name, 'My awesome policy')
+        self.assertEqual(rule.action, 'drop')
+        self.assertEqual(rule.direction, 'out')
+        self.assertEqual(rule.dst_ip, '23.0.0.0/32')
+        self.assertEqual(rule.ip_proto, 'tcp')
+        self.assertEqual(rule.dst_port, None)
+        self.assertEqual(rule.src_ip, None)
+        self.assertEqual(rule.src_port, None)
+        self.assertEqual(rule.comment, 'Drop traffic from the VM to IP address 23.0.0.0/32')
+
+    def test_ex_create_firewall_policy_no_rules(self):
+        CloudSigmaMockHttp.type = 'CREATE_NO_RULES'
+        policy = self.driver.ex_create_firewall_policy(name='test policy 1')
+
+        self.assertEqual(policy.name, 'test policy 1')
+        self.assertEqual(policy.rules, [])
+
+    def test_ex_create_firewall_policy_with_rules(self):
+        CloudSigmaMockHttp.type = 'CREATE_WITH_RULES'
+        rules = [
+            {
+                'action': 'accept',
+                'direction': 'out',
+                'ip_proto': 'tcp',
+                'src_ip': '127.0.0.1',
+                'dst_ip': '127.0.0.1'
+            }
+        ]
+
+        policy = self.driver.ex_create_firewall_policy(name='test policy 2',
+                                                       rules=rules)
+        rule = policy.rules[0]
+
+        self.assertEqual(policy.name, 'test policy 2')
+        self.assertEqual(len(policy.rules), 1)
+
+        self.assertEqual(rule.action, 'accept')
+        self.assertEqual(rule.direction, 'out')
+        self.assertEqual(rule.ip_proto, 'tcp')
+
+    def test_ex_attach_firewall_policy(self):
+        policy = self.driver.ex_list_firewall_policies()[0]
+        node = self.driver.list_nodes()[0]
+
+        CloudSigmaMockHttp.type = 'ATTACH_POLICY'
+        updated_node = self.driver.ex_attach_firewall_policy(policy=policy,
+                                                             node=node)
+        nic = updated_node.extra['nics'][0]
+        self.assertEqual(nic['firewall_policy']['uuid'],
+                         '461dfb8c-e641-43d7-a20e-32e2aa399086')
+
+    def test_ex_attach_firewall_policy_inexistent_nic(self):
+        policy = self.driver.ex_list_firewall_policies()[0]
+        node = self.driver.list_nodes()[0]
+
+        nic_mac = 'inexistent'
+        expected_msg = 'Cannot find the NIC interface to attach a policy to'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                self.driver.ex_attach_firewall_policy,
+                                policy=policy,
+                                node=node,
+                                nic_mac=nic_mac)
+
+    def test_ex_delete_firewall_policy(self):
+        policy = self.driver.ex_list_firewall_policies()[0]
+        status = self.driver.ex_delete_firewall_policy(policy=policy)
+        self.assertTrue(status)
+
+    def test_ex_list_tags(self):
+        tags = self.driver.ex_list_tags()
+
+        tag = tags[0]
+        self.assertEqual(tag.id, 'a010ec41-2ead-4630-a1d0-237fa77e4d4d')
+        self.assertEqual(tag.name, 'test tag 2')
+
+    def test_ex_get_tag(self):
+        tag = self.driver.ex_get_tag(tag_id='a010ec41-2ead-4630-a1d0-237fa77e4d4d')
+
+        self.assertEqual(tag.id, 'a010ec41-2ead-4630-a1d0-237fa77e4d4d')
+        self.assertEqual(tag.name, 'test tag 2')
+
+    def test_ex_create_tag(self):
+        tag = self.driver.ex_create_tag(name='test tag 3')
+        self.assertEqual(tag.name, 'test tag 3')
+
+    def test_ex_create_tag_with_resources(self):
+        CloudSigmaMockHttp.type = 'WITH_RESOURCES'
+        resource_uuids = ['1']
+        tag = self.driver.ex_create_tag(name='test tag 3',
+                                        resource_uuids=resource_uuids)
+        self.assertEqual(tag.name, 'test tag 3')
+        self.assertEqual(tag.resources, resource_uuids)
+
+    def test_ex_tag_resource(self):
+        node = self.driver.list_nodes()[0]
+        tag = self.driver.ex_list_tags()[0]
+
+        updated_tag = self.driver.ex_tag_resource(resource=node, tag=tag)
+        self.assertEqual(updated_tag.name, 'test tag 3')
+
+    def test_ex_tag_resources(self):
+        nodes = self.driver.list_nodes()
+        tag = self.driver.ex_list_tags()[0]
+
+        updated_tag = self.driver.ex_tag_resources(resources=nodes, tag=tag)
+        self.assertEqual(updated_tag.name, 'test tag 3')
+
+    def test_ex_tag_resource_invalid_resource_object(self):
+        tag = self.driver.ex_list_tags()[0]
+
+        expected_msg = 'Resource doesn\'t have id attribute'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                self.driver.ex_tag_resource, tag=tag,
+                                resource={})
+
+    def test_ex_delete_tag(self):
+        tag = self.driver.ex_list_tags()[0]
+        status = self.driver.ex_delete_tag(tag=tag)
+        self.assertTrue(status)
+
+    def test_ex_get_balance(self):
+        balance = self.driver.ex_get_balance()
+        self.assertEqual(balance['balance'], '10.00')
+        self.assertEqual(balance['currency'], 'USD')
+
+    def test_ex_get_pricing(self):
+        pricing = self.driver.ex_get_pricing()
+
+        self.assertTrue('current' in pricing)
+        self.assertTrue('next' in pricing)
+        self.assertTrue('objects' in pricing)
+
+    def test_ex_get_usage(self):
+        pricing = self.driver.ex_get_usage()
+
+        self.assertTrue('balance' in pricing)
+        self.assertTrue('usage' in pricing)
+
+    def test_ex_list_subscriptions(self):
+        subscriptions = self.driver.ex_list_subscriptions()
+
+        subscription = subscriptions[0]
+        self.assertEqual(len(subscriptions), 5)
+        self.assertEqual(subscription.id, '7272')
+        self.assertEqual(subscription.resource, 'vlan')
+        self.assertEqual(subscription.amount, '1')
+        self.assertEqual(subscription.period, '345 days, 0:00:00')
+        self.assertEqual(subscription.status, 'active')
+        self.assertEqual(subscription.price, '0E-20')
+
+    def test_ex_list_subscriptions_status_filterting(self):
+        CloudSigmaMockHttp.type = 'STATUS_FILTER'
+        self.driver.ex_list_subscriptions(status='active')
+
+    def test_ex_list_subscriptions_resource_filterting(self):
+        CloudSigmaMockHttp.type = 'RESOURCE_FILTER'
+        resources = ['cpu', 'mem']
+        self.driver.ex_list_subscriptions(resources=resources)
+
+    def test_ex_toggle_subscription_auto_renew(self):
+        subscription = self.driver.ex_list_subscriptions()[0]
+        status = self.driver.ex_toggle_subscription_auto_renew(subscription=
+                                                               subscription)
+        self.assertTrue(status)
+
+    def test_ex_list_capabilities(self):
+        capabilities = self.driver.ex_list_capabilities()
+        self.assertEqual(capabilities['servers']['cpu']['min'], 250)
+
+    def test_wait_for_drive_state_transition_timeout(self):
+        drive = self.driver.ex_list_drives()[0]
+        state = 'timeout'
+
+        expected_msg = 'Timed out while waiting for drive transition'
+        self.assertRaisesRegexp(Exception, expected_msg,
+                                self.driver._wait_for_drive_state_transition,
+                                drive=drive, state=state,
+                                timeout=0.5)
+
+    def test_wait_for_drive_state_transition_success(self):
+        drive = self.driver.ex_list_drives()[0]
+        state = 'unmounted'
+
+        drive = self.driver._wait_for_drive_state_transition(drive=drive,
+                                                             state=state,
+                                                             timeout=0.5)
+        self.assertEqual(drive.status, state)
+
+
+class CloudSigmaAPI20DirectTestCase(CloudSigmaAPI20BaseTestCase,
+                                    unittest.TestCase):
+    driver_klass = CloudSigma_2_0_NodeDriver
+    driver_args = ('foo', 'bar')
+    driver_kwargs = {}
+
+
+class CloudSigmaAPI20IndirectTestCase(CloudSigmaAPI20BaseTestCase,
+                                      unittest.TestCase):
+    driver_klass = CloudSigmaNodeDriver
+    driver_args = ('foo', 'bar')
+    driver_kwargs = {'api_version': '2.0'}
+
+
+class CloudSigmaMockHttp(MockHttpTestCase):
+    fixtures = ComputeFileFixtures('cloudsigma_2_0')
+
+    def _api_2_0_servers_detail_INVALID_CREDS(self, method, url, body, headers):
+        body = self.fixtures.load('libdrives.json')
+        return (httplib.UNAUTHORIZED, body, {},
+                httplib.responses[httplib.UNAUTHORIZED])
+
+    def _api_2_0_libdrives(self, method, url, body, headers):
+        body = self.fixtures.load('libdrives.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_servers_detail(self, method, url, body, headers):
+        body = self.fixtures.load('servers_detail_mixed_state.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911(self, method, url, body, headers):
+        body = ''
+        return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.NO_CONTENT])
+
+    def _api_2_0_servers(self, method, url, body, headers):
+        if method == 'POST':
+            # create_node
+            body = self.fixtures.load('servers_create.json')
+            return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_start(self, method, url, body, headers):
+        body = self.fixtures.load('start_success.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_AVOID_MODE_start(self, method, url, body, headers):
+        self.assertUrlContainsQueryParams(url, {'avoid': '1,2'})
+
+        body = self.fixtures.load('start_success.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_ALREADY_STARTED_start(self, method, url, body, headers):
+        body = self.fixtures.load('start_already_started.json')
+        return (httplib.FORBIDDEN, body, {}, httplib.responses[httplib.FORBIDDEN])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_stop(self, method, url, body, headers):
+        body = self.fixtures.load('stop_success.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_ALREADY_STOPPED_stop(self, method, url, body, headers):
+        body = self.fixtures.load('stop_already_stopped.json')
+        return (httplib.FORBIDDEN, body, {}, httplib.responses[httplib.FORBIDDEN])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_clone(self, method, url, body, headers):
+        body = self.fixtures.load('servers_clone.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_open_vnc(self, method, url, body, headers):
+        body = self.fixtures.load('servers_open_vnc.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_action_close_vnc(self, method, url, body, headers):
+        body = self.fixtures.load('servers_close_vnc.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_drives_detail(self, method, url, body, headers):
+        body = self.fixtures.load('drives_detail.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_drives_b02311e2_a83c_4c12_af10_b30d51c86913(self, method, url, body, headers):
+        body = self.fixtures.load('drives_get.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_drives_9d1d2cf3_08c1_462f_8485_f4b073560809(self, method, url, body, headers):
+        body = self.fixtures.load('drives_get.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_drives_CREATE(self, method, url, body, headers):
+        body = self.fixtures.load('drives_create.json')
+        return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_drives_9d1d2cf3_08c1_462f_8485_f4b073560809_action_clone(self, method, url, body, headers):
+        body = self.fixtures.load('drives_clone.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_drives_5236b9ee_f735_42fd_a236_17558f9e12d3_action_clone(self, method, url, body, headers):
+        body = self.fixtures.load('drives_clone.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_drives_b02311e2_a83c_4c12_af10_b30d51c86913_action_resize(self, method, url, body, headers):
+        body = self.fixtures.load('drives_resize.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_drives_9d1d2cf3_08c1_462f_8485_f4b073560809_action_resize(self, method, url, body, headers):
+        body = self.fixtures.load('drives_resize.json')
+        return (httplib.ACCEPTED, body, {}, httplib.responses[httplib.ACCEPTED])
+
+    def _api_2_0_fwpolicies_detail(self, method, url, body, headers):
+        body = self.fixtures.load('fwpolicies_detail.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_fwpolicies_CREATE_NO_RULES(self, method, url, body, headers):
+        body = self.fixtures.load('fwpolicies_create_no_rules.json')
+        return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_fwpolicies_CREATE_WITH_RULES(self, method, url, body, headers):
+        body = self.fixtures.load('fwpolicies_create_with_rules.json')
+        return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_servers_9de75ed6_fd33_45e2_963f_d405f31fd911_ATTACH_POLICY(self, method, url, body, headers):
+        body = self.fixtures.load('servers_attach_policy.json')
+        return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_fwpolicies_0e339282_0cb5_41ac_a9db_727fb62ff2dc(self, method, url, body, headers):
+        if method == 'DELETE':
+            body = ''
+            return (httplib.NO_CONTENT, body, {},
+                    httplib.responses[httplib.NO_CONTENT])
+
+    def _api_2_0_tags_detail(self, method, url, body, headers):
+        body = self.fixtures.load('tags_detail.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_tags(self, method, url, body, headers):
+        if method == 'POST':
+            body = self.fixtures.load('tags_create.json')
+            return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_tags_WITH_RESOURCES(self, method, url, body, headers):
+        if method == 'POST':
+            body = self.fixtures.load('tags_create_with_resources.json')
+            return (httplib.CREATED, body, {}, httplib.responses[httplib.CREATED])
+
+    def _api_2_0_tags_a010ec41_2ead_4630_a1d0_237fa77e4d4d(self, method, url, body, headers):
+        if method == 'GET':
+            # ex_get_tag
+            body = self.fixtures.load('tags_get.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+        elif method == 'PUT':
+            # ex_tag_resource
+            body = self.fixtures.load('tags_update.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+        elif method == 'DELETE':
+            # ex_delete_tag
+            body = ''
+            return (httplib.NO_CONTENT, body, {},
+                    httplib.responses[httplib.NO_CONTENT])
+
+    def _api_2_0_balance(self, method, url, body, headers):
+        body = self.fixtures.load('balance.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_pricing(self, method, url, body, headers):
+        body = self.fixtures.load('pricing.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_currentusage(self, method, url, body, headers):
+        body = self.fixtures.load('currentusage.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_subscriptions(self, method, url, body, headers):
+        body = self.fixtures.load('subscriptions.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_subscriptions_STATUS_FILTER(self, method, url, body, headers):
+        self.assertUrlContainsQueryParams(url, {'status': 'active'})
+
+        body = self.fixtures.load('subscriptions.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_subscriptions_RESOURCE_FILTER(self, method, url, body, headers):
+        expected_params = {'resource': 'cpu,mem', 'status': 'all'}
+        self.assertUrlContainsQueryParams(url, expected_params)
+
+        body = self.fixtures.load('subscriptions.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_subscriptions_7272_action_auto_renew(self, method, url, body, headers):
+        body = ''
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _api_2_0_capabilities(self, method, url, body, headers):
+        body = self.fixtures.load('capabilities.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())


Mime
View raw message