diff --git a/doc/v3/api_samples/os-cells/cells-capacities-resp.json b/doc/v3/api_samples/os-cells/cells-capacities-resp.json
new file mode 100644
index 000000000000..5e067dd3aa36
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-capacities-resp.json
@@ -0,0 +1,26 @@
+{
+ "cell": {
+ "capacities": {
+ "disk_free": {
+ "total_mb": 1052672,
+ "units_by_mb": {
+ "0": 0,
+ "163840": 5,
+ "20480": 46,
+ "40960": 23,
+ "81920": 11
+ }
+ },
+ "ram_free": {
+ "total_mb": 7680,
+ "units_by_mb": {
+ "16384": 0,
+ "2048": 3,
+ "4096": 1,
+ "512": 13,
+ "8192": 0
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-capacities-resp.xml b/doc/v3/api_samples/os-cells/cells-capacities-resp.xml
new file mode 100644
index 000000000000..fd99b8cb41e5
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-capacities-resp.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-get-resp.json b/doc/v3/api_samples/os-cells/cells-get-resp.json
new file mode 100644
index 000000000000..62eb8ec31d20
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-get-resp.json
@@ -0,0 +1,9 @@
+{
+ "cell": {
+ "name": "cell3",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username3"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-get-resp.xml b/doc/v3/api_samples/os-cells/cells-get-resp.xml
new file mode 100644
index 000000000000..12256a5bdcef
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-get-resp.xml
@@ -0,0 +1,2 @@
+
+ |
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-list-empty-resp.json b/doc/v3/api_samples/os-cells/cells-list-empty-resp.json
new file mode 100644
index 000000000000..5325a4e855e2
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-list-empty-resp.json
@@ -0,0 +1,3 @@
+{
+ "cells": []
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-list-empty-resp.xml b/doc/v3/api_samples/os-cells/cells-list-empty-resp.xml
new file mode 100644
index 000000000000..6ac77b4bd8c5
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-list-empty-resp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-list-resp.json b/doc/v3/api_samples/os-cells/cells-list-resp.json
new file mode 100644
index 000000000000..97ea4c6dd32d
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-list-resp.json
@@ -0,0 +1,39 @@
+{
+ "cells": [
+ {
+ "name": "cell1",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username1"
+ },
+ {
+ "name": "cell3",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username3"
+ },
+ {
+ "name": "cell5",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username5"
+ },
+ {
+ "name": "cell2",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "parent",
+ "username": "username2"
+ },
+ {
+ "name": "cell4",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "parent",
+ "username": "username4"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-cells/cells-list-resp.xml b/doc/v3/api_samples/os-cells/cells-list-resp.xml
new file mode 100644
index 000000000000..7d697bb91868
--- /dev/null
+++ b/doc/v3/api_samples/os-cells/cells-list-resp.xml
@@ -0,0 +1,8 @@
+
+
+ |
+ |
+ |
+ |
+ |
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json b/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json
new file mode 100644
index 000000000000..8127b212ccd5
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json
@@ -0,0 +1,5 @@
+{
+ "addFixedIp":{
+ "networkId": 1
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml b/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml
new file mode 100644
index 000000000000..ee4b549a8358
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml
@@ -0,0 +1,3 @@
+
+ 1
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json b/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json
new file mode 100644
index 000000000000..cc2cff278679
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json
@@ -0,0 +1,5 @@
+{
+ "remove_fixed_ip":{
+ "address": "10.0.0.4"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml b/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml
new file mode 100644
index 000000000000..e89050ce6de0
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml
@@ -0,0 +1,3 @@
+
+ 10.0.0.4
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/server-post-req.json b/doc/v3/api_samples/os-multinic/server-post-req.json
new file mode 100644
index 000000000000..d41985a1bc39
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/server-post-req.json
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "image_ref" : "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
+ "flavor_ref" : "http://openstack.example.com/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/server-post-req.xml b/doc/v3/api_samples/os-multinic/server-post-req.xml
new file mode 100644
index 000000000000..598839cf6a3a
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/server-post-req.xml
@@ -0,0 +1,19 @@
+
+
+
+ Apache1
+
+
+
+ ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
+ dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
+ IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
+ c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
+ QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
+ ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
+ dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
+ c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
+ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
+
+
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/server-post-resp.json b/doc/v3/api_samples/os-multinic/server-post-resp.json
new file mode 100644
index 000000000000..86eea81c4d93
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/server-post-resp.json
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "admin_pass": "5Y9rR4XaM8Qg",
+ "id": "bbe8d469-e8cb-49b1-96d8-f93b68c82355",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v3/servers/bbe8d469-e8cb-49b1-96d8-f93b68c82355",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/servers/bbe8d469-e8cb-49b1-96d8-f93b68c82355",
+ "rel": "bookmark"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-multinic/server-post-resp.xml b/doc/v3/api_samples/os-multinic/server-post-resp.xml
new file mode 100644
index 000000000000..55b0d0d8c2d2
--- /dev/null
+++ b/doc/v3/api_samples/os-multinic/server-post-resp.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.json.tpl
new file mode 100644
index 000000000000..5e067dd3aa36
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.json.tpl
@@ -0,0 +1,26 @@
+{
+ "cell": {
+ "capacities": {
+ "disk_free": {
+ "total_mb": 1052672,
+ "units_by_mb": {
+ "0": 0,
+ "163840": 5,
+ "20480": 46,
+ "40960": 23,
+ "81920": 11
+ }
+ },
+ "ram_free": {
+ "total_mb": 7680,
+ "units_by_mb": {
+ "16384": 0,
+ "2048": 3,
+ "4096": 1,
+ "512": 13,
+ "8192": 0
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.xml.tpl
new file mode 100644
index 000000000000..fd99b8cb41e5
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-capacities-resp.xml.tpl
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.json.tpl
new file mode 100644
index 000000000000..62eb8ec31d20
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.json.tpl
@@ -0,0 +1,9 @@
+{
+ "cell": {
+ "name": "cell3",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username3"
+ }
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.xml.tpl
new file mode 100644
index 000000000000..12256a5bdcef
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-get-resp.xml.tpl
@@ -0,0 +1,2 @@
+
+ |
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.json.tpl
new file mode 100644
index 000000000000..5325a4e855e2
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.json.tpl
@@ -0,0 +1,3 @@
+{
+ "cells": []
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.xml.tpl
new file mode 100644
index 000000000000..6ac77b4bd8c5
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-empty-resp.xml.tpl
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.json.tpl
new file mode 100644
index 000000000000..97ea4c6dd32d
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.json.tpl
@@ -0,0 +1,39 @@
+{
+ "cells": [
+ {
+ "name": "cell1",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username1"
+ },
+ {
+ "name": "cell3",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username3"
+ },
+ {
+ "name": "cell5",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "child",
+ "username": "username5"
+ },
+ {
+ "name": "cell2",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "parent",
+ "username": "username2"
+ },
+ {
+ "name": "cell4",
+ "rpc_host": null,
+ "rpc_port": null,
+ "type": "parent",
+ "username": "username4"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.xml.tpl
new file mode 100644
index 000000000000..7d697bb91868
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-cells/cells-list-resp.xml.tpl
@@ -0,0 +1,8 @@
+
+
+ |
+ |
+ |
+ |
+ |
+
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json.tpl
new file mode 100644
index 000000000000..98dca5405a0b
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.json.tpl
@@ -0,0 +1,5 @@
+{
+ "add_fixed_ip":{
+ "network_id": %(networkId)s
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml.tpl
new file mode 100644
index 000000000000..c3b1b314cfda
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-add-fixed-ip-req.xml.tpl
@@ -0,0 +1,3 @@
+
+ %(networkId)s
+
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json.tpl
new file mode 100644
index 000000000000..03fec22486ad
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.json.tpl
@@ -0,0 +1,5 @@
+{
+ "remove_fixed_ip":{
+ "address": "%(ip)s"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml.tpl
new file mode 100644
index 000000000000..424338039922
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/multinic-remove-fixed-ip-req.xml.tpl
@@ -0,0 +1,3 @@
+
+ %(ip)s
+
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.json.tpl
new file mode 100644
index 000000000000..1dcb63e3b2ae
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "image_ref" : "%(host)s/openstack/images/%(image_id)s",
+ "flavor_ref" : "%(host)s/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.xml.tpl
new file mode 100644
index 000000000000..ddb5ea78c4b5
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-req.xml.tpl
@@ -0,0 +1,19 @@
+
+
+
+ Apache1
+
+
+
+ ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
+ dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
+ IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
+ c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
+ QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
+ ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
+ dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
+ c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
+ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
+
+
+
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.json.tpl
new file mode 100644
index 000000000000..6c3100fbec86
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "admin_pass": "%(password)s",
+ "id": "%(id)s",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v3/servers/%(uuid)s",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/servers/%(uuid)s",
+ "rel": "bookmark"
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.xml.tpl
new file mode 100644
index 000000000000..3470373e171f
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-multinic/server-post-resp.xml.tpl
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/nova/tests/integrated/v3/test_cells.py b/nova/tests/integrated/v3/test_cells.py
new file mode 100644
index 000000000000..80b9bde9c20f
--- /dev/null
+++ b/nova/tests/integrated/v3/test_cells.py
@@ -0,0 +1,112 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright 2012 Nebula, Inc.
+# Copyright 2013 IBM Corp.
+#
+# Licensed 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.
+
+from nova.cells import rpcapi as cells_rpcapi
+from nova.cells import state
+from nova import db
+from nova.db.sqlalchemy import models
+from nova import exception
+from nova.tests.integrated.v3 import api_sample_base
+
+
+class CellsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
+ extension_name = "os-cells"
+
+ def setUp(self):
+ # db_check_interval < 0 makes cells manager always hit the DB
+ self.flags(enable=True, db_check_interval=-1, group='cells')
+ super(CellsSampleJsonTest, self).setUp()
+ self._stub_cells()
+
+ def _stub_cells(self, num_cells=5):
+ self.cell_list = []
+ self.cells_next_id = 1
+
+ def _fake_cell_get_all(context):
+ return self.cell_list
+
+ def _fake_cell_get(inst, context, cell_name):
+ for cell in self.cell_list:
+ if cell['name'] == cell_name:
+ return cell
+ raise exception.CellNotFound(cell_name=cell_name)
+
+ for x in xrange(num_cells):
+ cell = models.Cell()
+ our_id = self.cells_next_id
+ self.cells_next_id += 1
+ cell.update({'id': our_id,
+ 'name': 'cell%s' % our_id,
+ 'transport_url': 'rabbit://username%s@/' % our_id,
+ 'is_parent': our_id % 2 == 0})
+ self.cell_list.append(cell)
+
+ self.stubs.Set(db, 'cell_get_all', _fake_cell_get_all)
+ self.stubs.Set(cells_rpcapi.CellsAPI, 'cell_get', _fake_cell_get)
+
+ def test_cells_empty_list(self):
+ # Override this
+ self._stub_cells(num_cells=0)
+ response = self._do_get('os-cells')
+ subs = self._get_regexes()
+ self._verify_response('cells-list-empty-resp', subs, response, 200)
+
+ def test_cells_list(self):
+ response = self._do_get('os-cells')
+ subs = self._get_regexes()
+ self._verify_response('cells-list-resp', subs, response, 200)
+
+ def test_cells_get(self):
+ response = self._do_get('os-cells/cell3')
+ subs = self._get_regexes()
+ self._verify_response('cells-get-resp', subs, response, 200)
+
+ def test_get_cell_capacity(self):
+ self._mock_cell_capacity()
+ state_manager = state.CellStateManager()
+ my_state = state_manager.get_my_state()
+ response = self._do_get('os-cells/%s/capacities' %
+ my_state.name)
+ subs = self._get_regexes()
+ return self._verify_response('cells-capacities-resp',
+ subs, response, 200)
+
+ def test_get_all_cells_capacity(self):
+ self._mock_cell_capacity()
+ response = self._do_get('os-cells/capacities')
+ subs = self._get_regexes()
+ return self._verify_response('cells-capacities-resp',
+ subs, response, 200)
+
+ def _mock_cell_capacity(self):
+ self.mox.StubOutWithMock(self.cells.manager.state_manager,
+ 'get_our_capacities')
+ response = {"ram_free":
+ {"units_by_mb": {"8192": 0, "512": 13,
+ "4096": 1, "2048": 3, "16384": 0},
+ "total_mb": 7680},
+ "disk_free":
+ {"units_by_mb": {"81920": 11, "20480": 46,
+ "40960": 23, "163840": 5, "0": 0},
+ "total_mb": 1052672}
+ }
+ self.cells.manager.state_manager.get_our_capacities(). \
+ AndReturn(response)
+ self.mox.ReplayAll()
+
+
+class CellsSampleXmlTest(CellsSampleJsonTest):
+ ctype = 'xml'
diff --git a/nova/tests/integrated/v3/test_multinic.py b/nova/tests/integrated/v3/test_multinic.py
new file mode 100644
index 000000000000..8ba5ed21f1bd
--- /dev/null
+++ b/nova/tests/integrated/v3/test_multinic.py
@@ -0,0 +1,54 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright 2012 Nebula, Inc.
+# Copyright 2013 IBM Corp.
+#
+# Licensed 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.
+
+from nova.tests.integrated.v3 import test_servers
+
+
+class MultinicSampleJsonTest(test_servers.ServersSampleBase):
+ extension_name = "os-multinic"
+
+ def _disable_instance_dns_manager(self):
+ # NOTE(markmc): it looks like multinic and instance_dns_manager are
+ # incompatible. See:
+ # https://bugs.launchpad.net/nova/+bug/1213251
+ self.flags(
+ instance_dns_manager='nova.network.noop_dns_driver.NoopDNSDriver')
+
+ def setUp(self):
+ self._disable_instance_dns_manager()
+ super(MultinicSampleJsonTest, self).setUp()
+ self.uuid = self._post_server()
+
+ def _add_fixed_ip(self):
+ subs = {"networkId": 1}
+ response = self._do_post('servers/%s/action' % (self.uuid),
+ 'multinic-add-fixed-ip-req', subs)
+ self.assertEqual(response.status, 202)
+
+ def test_add_fixed_ip(self):
+ self._add_fixed_ip()
+
+ def test_remove_fixed_ip(self):
+ self._add_fixed_ip()
+
+ subs = {"ip": "10.0.0.4"}
+ response = self._do_post('servers/%s/action' % (self.uuid),
+ 'multinic-remove-fixed-ip-req', subs)
+ self.assertEqual(response.status, 202)
+
+
+class MultinicSampleXmlTest(MultinicSampleJsonTest):
+ ctype = "xml"