diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json
index 155a877c23..f34eec0a34 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.json
+++ b/doc/api_samples/all_extensions/extensions-get-resp.json
@@ -136,6 +136,14 @@
"namespace": "http://docs.openstack.org/compute/ext/deferred-delete/api/v1.1",
"updated": "2011-09-01T00:00:00+00:00"
},
+ {
+ "alias": "os-fixed-ips",
+ "description": "Fixed IPs support",
+ "links": [],
+ "name": "FixedIPs",
+ "namespace": "http://docs.openstack.org/compute/ext/fixed_ips/api/v2",
+ "updated": "2012-10-18T13:25:27-06:00"
+ },
{
"alias": "os-flavor-access",
"description": "Flavor access supprt",
@@ -200,6 +208,22 @@
"namespace": "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1",
"updated": "2011-06-16T00:00:00+00:00"
},
+ {
+ "alias": "os-floating-ips-bulk",
+ "description": "Bulk handling of Floating IPs",
+ "links": [],
+ "name": "FloatingIpsBulk",
+ "namespace": "http://docs.openstack.org/compute/ext/floating_ips_bulk/api/v2",
+ "updated": "2012-10-29T13:25:27-06:00"
+ },
+ {
+ "alias": "os-fping",
+ "description": "Fping Management Extension.",
+ "links": [],
+ "name": "Fping",
+ "namespace": "http://docs.openstack.org/compute/ext/fping/api/v1.1",
+ "updated": "2012-07-06T00:00:00+00:00"
+ },
{
"alias": "os-hosts",
"description": "Admin-only host administration",
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml
index ad10c671b3..78dd425a7e 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.xml
+++ b/doc/api_samples/all_extensions/extensions-get-resp.xml
@@ -63,6 +63,9 @@
Instance deferred delete
+
+ Fixed IPs support
+
Flavor access supprt
@@ -89,6 +92,12 @@
Floating IPs support
+
+ Bulk handling of Floating IPs
+
+
+ Fping Management Extension.
+
Admin-only host administration
diff --git a/doc/api_samples/limit-get-resp.json b/doc/api_samples/limit-get-resp.json
index 1c5aa7a745..e11c3ee8ea 100644
--- a/doc/api_samples/limit-get-resp.json
+++ b/doc/api_samples/limit-get-resp.json
@@ -4,34 +4,34 @@
"maxImageMeta": 128,
"maxPersonality": 5,
"maxPersonalitySize": 10240,
+ "maxSecurityGroupRules": 20,
+ "maxSecurityGroups": 10,
"maxServerMeta": 128,
"maxTotalCores": 20,
"maxTotalFloatingIps": 10,
"maxTotalInstances": 10,
"maxTotalKeypairs": 100,
- "maxTotalRAMSize": 51200,
- "maxSecurityGroups": 10,
- "maxSecurityGroupRules": 20
+ "maxTotalRAMSize": 51200
},
"rate": [
{
"limit": [
{
- "next-available": "2012-08-31T22:36:27Z",
+ "next-available": "2012-11-27T17:22:18Z",
"remaining": 10,
"unit": "MINUTE",
"value": 10,
"verb": "POST"
},
{
- "next-available": "2012-08-31T22:36:27Z",
+ "next-available": "2012-11-27T17:22:18Z",
"remaining": 10,
"unit": "MINUTE",
"value": 10,
"verb": "PUT"
},
{
- "next-available": "2012-08-31T22:36:27Z",
+ "next-available": "2012-11-27T17:22:18Z",
"remaining": 100,
"unit": "MINUTE",
"value": 100,
@@ -44,7 +44,7 @@
{
"limit": [
{
- "next-available": "2012-08-31T22:36:27Z",
+ "next-available": "2012-11-27T17:22:18Z",
"remaining": 50,
"unit": "DAY",
"value": 50,
@@ -57,7 +57,7 @@
{
"limit": [
{
- "next-available": "2012-08-31T22:36:27Z",
+ "next-available": "2012-11-27T17:22:18Z",
"remaining": 3,
"unit": "MINUTE",
"value": 3,
@@ -66,7 +66,20 @@
],
"regex": ".*changes-since.*",
"uri": "*changes-since*"
+ },
+ {
+ "limit": [
+ {
+ "next-available": "2012-11-27T17:22:18Z",
+ "remaining": 12,
+ "unit": "HOUR",
+ "value": 12,
+ "verb": "GET"
+ }
+ ],
+ "regex": "^/os-fping",
+ "uri": "*/os-fping"
}
]
}
-}
+}
\ No newline at end of file
diff --git a/doc/api_samples/limit-get-resp.xml b/doc/api_samples/limit-get-resp.xml
index a47e0b22fb..d8c1970919 100644
--- a/doc/api_samples/limit-get-resp.xml
+++ b/doc/api_samples/limit-get-resp.xml
@@ -2,28 +2,31 @@
-
-
-
+
+
+
-
+
-
+
+
+
+
-
+
+
+
-
-
-
+
\ No newline at end of file
diff --git a/doc/api_samples/os-cloudpipe/cloud-pipe-create-resp.json b/doc/api_samples/os-cloudpipe/cloud-pipe-create-resp.json
index 8c555bf99d..a66b456c13 100644
--- a/doc/api_samples/os-cloudpipe/cloud-pipe-create-resp.json
+++ b/doc/api_samples/os-cloudpipe/cloud-pipe-create-resp.json
@@ -1,5 +1,3 @@
{
- "cloudpipe": {
- "instance_id": "72afecab-24b0-437e-b1d9-88a83be701b3"
- }
+ "instance_id": "1e9b8425-34af-488e-b969-4d46f4a6382e"
}
\ No newline at end of file
diff --git a/doc/api_samples/os-cloudpipe/cloud-pipe-get-resp.json b/doc/api_samples/os-cloudpipe/cloud-pipe-get-resp.json
index 9efac48bba..d6773dfa5a 100644
--- a/doc/api_samples/os-cloudpipe/cloud-pipe-get-resp.json
+++ b/doc/api_samples/os-cloudpipe/cloud-pipe-get-resp.json
@@ -1,15 +1,13 @@
{
"cloudpipes": [
{
- "cloudpipe": {
- "created_at": "2012-09-25T18:18:55Z",
- "instance_id": "72afecab-24b0-437e-b1d9-88a83be701b3",
- "internal_ip": "192.168.0.3",
- "project_id": "cloudpipe-059f21e3-c20e-4efc-9e7a-eba2ab3c6f9a",
- "public_ip": "127.0.0.1",
- "public_port": 22,
- "state": "down"
- }
+ "created_at": "2012-11-27T17:18:01Z",
+ "instance_id": "27deecdb-baa3-4a26-9c82-32994b815b01",
+ "internal_ip": "192.168.0.3",
+ "project_id": "cloudpipe-fa1765bd-a352-49c7-a6b7-8ee108a3cb0c",
+ "public_ip": "127.0.0.1",
+ "public_port": 22,
+ "state": "down"
}
]
}
\ No newline at end of file
diff --git a/doc/api_samples/os-hosts/hosts-list-resp.json b/doc/api_samples/os-hosts/hosts-list-resp.json
index 760db64ff4..d4146c0823 100644
--- a/doc/api_samples/os-hosts/hosts-list-resp.json
+++ b/doc/api_samples/os-hosts/hosts-list-resp.json
@@ -1,24 +1,29 @@
{
"hosts": [
{
- "host_name": "c5a4acad61bc463ab5f60d164d942516",
+ "host_name": "787f4f6dda1b409bb8b2f9082349690e",
"service": "compute",
"zone": "nova"
},
{
- "host_name": "9112426abe5f4934a81b494fcdee8c5b",
+ "host_name": "a98b433151084aee8b1a986e28823b36",
"service": "cert",
"zone": "nova"
},
{
- "host_name": "d483b9e6124d47f2a6ad14e57716a778",
+ "host_name": "c56158d13a884a87abf9171efb7de9d8",
"service": "network",
"zone": "nova"
},
{
- "host_name": "3f9c73ba6d634092a70d6640f53930c8",
+ "host_name": "81d5cdcda0014918b3ebd3503a2e5c9a",
"service": "scheduler",
"zone": "nova"
+ },
+ {
+ "host_name": "6e48bfe1a3304b7b86154326328750ae",
+ "service": "conductor",
+ "zone": "nova"
}
]
}
\ No newline at end of file
diff --git a/doc/api_samples/os-hosts/hosts-list-resp.xml b/doc/api_samples/os-hosts/hosts-list-resp.xml
index 7defe04573..8266a5d491 100644
--- a/doc/api_samples/os-hosts/hosts-list-resp.xml
+++ b/doc/api_samples/os-hosts/hosts-list-resp.xml
@@ -1,7 +1,8 @@
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-used-limits/usedlimits-get-resp.json b/doc/api_samples/os-used-limits/usedlimits-get-resp.json
index f018be9beb..21ed3a0826 100644
--- a/doc/api_samples/os-used-limits/usedlimits-get-resp.json
+++ b/doc/api_samples/os-used-limits/usedlimits-get-resp.json
@@ -22,21 +22,21 @@
{
"limit": [
{
- "next-available": "2012-10-04T15:38:20Z",
+ "next-available": "2012-11-27T17:24:52Z",
"remaining": 10,
"unit": "MINUTE",
"value": 10,
"verb": "POST"
},
{
- "next-available": "2012-10-04T15:38:20Z",
+ "next-available": "2012-11-27T17:24:52Z",
"remaining": 10,
"unit": "MINUTE",
"value": 10,
"verb": "PUT"
},
{
- "next-available": "2012-10-04T15:38:20Z",
+ "next-available": "2012-11-27T17:24:52Z",
"remaining": 100,
"unit": "MINUTE",
"value": 100,
@@ -49,7 +49,7 @@
{
"limit": [
{
- "next-available": "2012-10-04T15:38:20Z",
+ "next-available": "2012-11-27T17:24:52Z",
"remaining": 50,
"unit": "DAY",
"value": 50,
@@ -62,7 +62,7 @@
{
"limit": [
{
- "next-available": "2012-10-04T15:38:20Z",
+ "next-available": "2012-11-27T17:24:52Z",
"remaining": 3,
"unit": "MINUTE",
"value": 3,
@@ -71,7 +71,20 @@
],
"regex": ".*changes-since.*",
"uri": "*changes-since*"
+ },
+ {
+ "limit": [
+ {
+ "next-available": "2012-11-27T17:24:52Z",
+ "remaining": 12,
+ "unit": "HOUR",
+ "value": 12,
+ "verb": "GET"
+ }
+ ],
+ "regex": "^/os-fping",
+ "uri": "*/os-fping"
}
]
}
-}
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-used-limits/usedlimits-get-resp.xml b/doc/api_samples/os-used-limits/usedlimits-get-resp.xml
index b86a41555a..745a4828a9 100644
--- a/doc/api_samples/os-used-limits/usedlimits-get-resp.xml
+++ b/doc/api_samples/os-used-limits/usedlimits-get-resp.xml
@@ -2,26 +2,27 @@
-
-
-
+
+
+
-
+
-
+
+
+
+
-
-
@@ -29,6 +30,8 @@
+
+
-
+
\ No newline at end of file
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index d82dd31545..3e6513c381 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -201,14 +201,46 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
'%(expected)s\n%(result)s') % locals())
return matched_value
+ def _verify_something(self, subs, expected, data):
+ result = self._pretty_data(data)
+ result = self._objectify(result)
+ return self._compare_result(subs, expected, result)
+
+ def generalize_subs(self, subs, vanilla_regexes):
+ """Give the test a chance to modify subs after the server response
+ was verified, and before the on-disk doc/api_samples file is checked.
+ This may be needed by some tests to convert exact matches expected
+ from the server into pattern matches to verify what is in the
+ sample file.
+
+ If there are no changes to be made, subs is returned unharmed.
+ """
+ return subs
+
def _verify_response(self, name, subs, response):
expected = self._read_template(name)
expected = self._objectify(expected)
- result = self._pretty_data(response.read())
- if self.generate_samples:
- self._write_sample(name, result)
- result = self._objectify(result)
- return self._compare_result(subs, expected, result)
+ with file(self._get_sample(name)) as sample:
+ sample_data = sample.read()
+ response_data = response.read()
+
+ try:
+ response_result = self._verify_something(subs, expected,
+ response_data)
+ # NOTE(danms): replace some of the subs with patterns for the
+ # doc/api_samples check, which won't have things like the
+ # correct compute host name. Also let the test do some of its
+ # own generalization, if necessary
+ vanilla_regexes = self._get_regexes()
+ subs['compute_host'] = vanilla_regexes['host_name']
+ subs['id'] = vanilla_regexes['id']
+ subs = self.generalize_subs(subs, vanilla_regexes)
+ self._verify_something(subs, expected, sample_data)
+ return response_result
+ except NoMatch:
+ if self.generate_samples:
+ self._write_sample(name, self._pretty_data(response_data))
+ raise
def _get_host(self):
return 'http://openstack.example.com'
@@ -264,8 +296,9 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
def _do_post(self, url, name, subs, method='POST'):
body = self._read_template(name) % subs
- if self.generate_samples:
- self._write_sample(name, body)
+ sample = self._get_sample(name)
+ if self.generate_samples and not os.path.exists(sample):
+ self._write_sample(name, body)
return self._get_response(url, method, body)
def _do_put(self, url, name, subs):
@@ -353,6 +386,10 @@ class ServersMetadataJsonTest(ServersSampleBase):
return uuid
+ def generalize_subs(self, subs, vanilla_regexes):
+ subs['value'] = '(Foo|Bar) Value'
+ return subs
+
def test_metadata_put_all(self):
"""Test setting all metadata for a server"""
subs = {'value': 'Foo Value'}
@@ -1021,6 +1058,10 @@ class FloatingIpsBulkXmlTest(FloatingIpsBulkJsonTest):
class KeyPairsSampleJsonTest(ApiSampleTestBase):
extension_name = "nova.api.openstack.compute.contrib.keypairs.Keypairs"
+ def generalize_subs(self, subs, vanilla_regexes):
+ subs['keypair_name'] = 'keypair-[0-9a-f-]+'
+ return subs
+
def test_keypairs_post(self, public_key=None):
"""Get api sample of key pairs post request"""
key_name = 'keypair-' + str(uuid.uuid4())
@@ -1155,6 +1196,10 @@ class CloudPipeSampleJsonTest(ApiSampleTestBase):
self.stubs.Set(CloudPipe, 'get_encoded_zip', get_user_data)
self.stubs.Set(NetworkManager, "get_network", network_api_get)
+ def generalize_subs(self, subs, vanilla_regexes):
+ subs['project_id'] = 'cloudpipe-[0-9a-f-]+'
+ return subs
+
def test_cloud_pipe_create(self):
"""Get api samples of cloud pipe extension creation"""
self.flags(vpn_image_id=fake.get_valid_image_id())