From 2a546a864518e085efe8f1e9089fd516f0dc4bbf Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 12 Jun 2025 16:44:58 +0100 Subject: [PATCH] tests: Use valid UUIDs for cinder resources This necessitates adding some missing return values for various mocks. Combined, this brings our tests closer to reality and will be needed once we add response schemas for these. Change-Id: I1ff23082d257f98e4f63b84b287a3c374a62bf0b Signed-off-by: Stephen Finucane --- .../v2.97/server-shares-create-tag-req.json | 6 ++ .../v2.97/server-shares-delete-req.json | 5 ++ .../os-snapshots/snapshot-create-resp.json | 4 +- .../os-snapshots/snapshots-detail-resp.json | 18 ++-- .../os-snapshots/snapshots-list-resp.json | 18 ++-- .../os-snapshots/snapshots-show-resp.json | 6 +- .../os-volumes/os-volumes-detail-resp.json | 4 +- .../os-volumes/os-volumes-get-resp.json | 6 +- .../os-volumes/os-volumes-index-resp.json | 6 +- .../os-volumes/os-volumes-post-req.json | 2 +- .../os-volumes/os-volumes-post-resp.json | 6 +- .../servers/v2.100/server-action-rebuild.json | 15 ++++ .../servers/v2.100/server-create-req.json | 25 ++++++ .../snapshot-create-resp.json.tpl | 2 +- .../snapshots-detail-resp.json.tpl | 12 +-- .../os-snapshots/snapshots-list-resp.json.tpl | 12 +-- .../os-snapshots/snapshots-show-resp.json.tpl | 4 +- .../os-volumes-detail-resp.json.tpl | 4 +- .../os-volumes/os-volumes-get-resp.json.tpl | 4 +- .../os-volumes/os-volumes-index-resp.json.tpl | 4 +- .../os-volumes/os-volumes-post-req.json.tpl | 2 +- .../os-volumes/os-volumes-post-resp.json.tpl | 4 +- .../api_sample_tests/test_snapshots.py | 6 +- .../api_sample_tests/test_volumes.py | 88 ++++--------------- .../api/openstack/compute/test_snapshots.py | 57 +++++------- .../compute/test_volume_attachments.py | 20 ++--- .../api/openstack/compute/test_volumes.py | 37 ++++---- nova/tests/unit/api/openstack/fakes.py | 76 +++++++++------- nova/tests/unit/fake_block_device.py | 3 +- nova/tests/unit/policies/test_snapshots.py | 15 ++++ .../unit/policies/test_volume_attachments.py | 1 + nova/tests/unit/policies/test_volumes.py | 30 ++++++- 32 files changed, 270 insertions(+), 232 deletions(-) create mode 100644 doc/api_samples/os-server-shares/v2.97/server-shares-create-tag-req.json create mode 100644 doc/api_samples/os-server-shares/v2.97/server-shares-delete-req.json create mode 100644 doc/api_samples/servers/v2.100/server-action-rebuild.json create mode 100644 doc/api_samples/servers/v2.100/server-create-req.json diff --git a/doc/api_samples/os-server-shares/v2.97/server-shares-create-tag-req.json b/doc/api_samples/os-server-shares/v2.97/server-shares-create-tag-req.json new file mode 100644 index 000000000000..0b1511345342 --- /dev/null +++ b/doc/api_samples/os-server-shares/v2.97/server-shares-create-tag-req.json @@ -0,0 +1,6 @@ +{ + "share": { + "share_id": "e8debdc0-447a-4376-a10a-4cd9122d7986", + "tag": "my-tag" + } +} \ No newline at end of file diff --git a/doc/api_samples/os-server-shares/v2.97/server-shares-delete-req.json b/doc/api_samples/os-server-shares/v2.97/server-shares-delete-req.json new file mode 100644 index 000000000000..bc05c4ccd22d --- /dev/null +++ b/doc/api_samples/os-server-shares/v2.97/server-shares-delete-req.json @@ -0,0 +1,5 @@ +{ + "share": { + "share_id": "e8debdc0-447a-4376-a10a-4cd9122d7986" + } +} \ No newline at end of file diff --git a/doc/api_samples/os-snapshots/snapshot-create-resp.json b/doc/api_samples/os-snapshots/snapshot-create-resp.json index a8dd57d8410e..e14754da48ff 100644 --- a/doc/api_samples/os-snapshots/snapshot-create-resp.json +++ b/doc/api_samples/os-snapshots/snapshot-create-resp.json @@ -1,9 +1,9 @@ { "snapshot": { - "createdAt": "2013-02-25T16:27:54.680544", + "createdAt": "2025-06-12T14:56:30.215430", "displayDescription": "Daily backup", "displayName": "snap-001", - "id": 100, + "id": "fe06e9f2-e6b0-47d1-a63e-c0a15ad51994", "size": 100, "status": "available", "volumeId": "521752a6-acf6-4b2d-bc7a-119f9148cd8c" diff --git a/doc/api_samples/os-snapshots/snapshots-detail-resp.json b/doc/api_samples/os-snapshots/snapshots-detail-resp.json index 796e522c439f..f8be58f26eb3 100644 --- a/doc/api_samples/os-snapshots/snapshots-detail-resp.json +++ b/doc/api_samples/os-snapshots/snapshots-detail-resp.json @@ -1,31 +1,31 @@ { "snapshots": [ { - "createdAt": "2013-02-25T16:27:54.671372", + "createdAt": "2025-06-12T14:56:30.070910", "displayDescription": "Default description", "displayName": "Default name", - "id": 100, + "id": "02d9627d-9e4d-42d7-aff2-3b23a0caf990", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "a41718ce-4f74-46cf-acb4-6ebfc435ad6e" }, { - "createdAt": "2013-02-25T16:27:54.671378", + "createdAt": "2025-06-12T14:56:30.070925", "displayDescription": "Default description", "displayName": "Default name", - "id": 101, + "id": "9780ef6b-6820-478b-8d01-c972e683a8aa", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "a41718ce-4f74-46cf-acb4-6ebfc435ad6e" }, { - "createdAt": "2013-02-25T16:27:54.671381", + "createdAt": "2025-06-12T14:56:30.070934", "displayDescription": "Default description", "displayName": "Default name", - "id": 102, + "id": "29b0f3f1-6cd7-4c65-b431-882cf54f158c", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "a41718ce-4f74-46cf-acb4-6ebfc435ad6e" } ] } \ No newline at end of file diff --git a/doc/api_samples/os-snapshots/snapshots-list-resp.json b/doc/api_samples/os-snapshots/snapshots-list-resp.json index 9b7cb412a854..f19ec3502374 100644 --- a/doc/api_samples/os-snapshots/snapshots-list-resp.json +++ b/doc/api_samples/os-snapshots/snapshots-list-resp.json @@ -1,31 +1,31 @@ { "snapshots": [ { - "createdAt": "2013-02-25T16:27:54.684999", + "createdAt": "2025-06-12T14:56:28.865898", "displayDescription": "Default description", "displayName": "Default name", - "id": 100, + "id": "f3ddb3ee-7fed-4237-ac25-1d4d8c0fb127", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "4fe5b5eb-694e-4ead-ba98-ecffc6ff1d21" }, { - "createdAt": "2013-02-25T16:27:54.685005", + "createdAt": "2025-06-12T14:56:28.865915", "displayDescription": "Default description", "displayName": "Default name", - "id": 101, + "id": "d018c6d5-0a75-4001-aef2-9f9df82feb6e", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "4fe5b5eb-694e-4ead-ba98-ecffc6ff1d21" }, { - "createdAt": "2013-02-25T16:27:54.685008", + "createdAt": "2025-06-12T14:56:28.865925", "displayDescription": "Default description", "displayName": "Default name", - "id": 102, + "id": "df0a2535-bab9-4bec-b03b-656f741b1c45", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "4fe5b5eb-694e-4ead-ba98-ecffc6ff1d21" } ] } \ No newline at end of file diff --git a/doc/api_samples/os-snapshots/snapshots-show-resp.json b/doc/api_samples/os-snapshots/snapshots-show-resp.json index d7b3f26e419f..9b58588abfe0 100644 --- a/doc/api_samples/os-snapshots/snapshots-show-resp.json +++ b/doc/api_samples/os-snapshots/snapshots-show-resp.json @@ -1,11 +1,11 @@ { "snapshot": { - "createdAt": "2013-02-25T16:27:54.724209", + "createdAt": "2025-06-12T14:56:28.922532", "displayDescription": "Default description", "displayName": "Default name", - "id": "100", + "id": "ec675a13-5be8-4077-8381-9d70a12f77fb", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "d7bccf30-48a2-4cfc-a9c0-71c5ee144f61" } } \ No newline at end of file diff --git a/doc/api_samples/os-volumes/os-volumes-detail-resp.json b/doc/api_samples/os-volumes/os-volumes-detail-resp.json index 6a92f5e0d57f..3dd879d6d25a 100644 --- a/doc/api_samples/os-volumes/os-volumes-detail-resp.json +++ b/doc/api_samples/os-volumes/os-volumes-detail-resp.json @@ -9,7 +9,7 @@ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "1999-01-01T01:01:01.000000", "displayDescription": "Volume Description", "displayName": "Volume Name", @@ -18,7 +18,7 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } ] } diff --git a/doc/api_samples/os-volumes/os-volumes-get-resp.json b/doc/api_samples/os-volumes/os-volumes-get-resp.json index 5c8429cb1ba7..c47c2aa1bcc0 100644 --- a/doc/api_samples/os-volumes/os-volumes-get-resp.json +++ b/doc/api_samples/os-volumes/os-volumes-get-resp.json @@ -8,7 +8,7 @@ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "2013-02-18T14:51:18.528085", "displayDescription": "Volume Description", "displayName": "Volume Name", @@ -17,6 +17,6 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } -} \ No newline at end of file +} diff --git a/doc/api_samples/os-volumes/os-volumes-index-resp.json b/doc/api_samples/os-volumes/os-volumes-index-resp.json index c0fa4b8917c3..86920e398ce2 100644 --- a/doc/api_samples/os-volumes/os-volumes-index-resp.json +++ b/doc/api_samples/os-volumes/os-volumes-index-resp.json @@ -9,7 +9,7 @@ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "2013-02-19T20:01:40.274897", "displayDescription": "Volume Description", "displayName": "Volume Name", @@ -18,7 +18,7 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } ] -} \ No newline at end of file +} diff --git a/doc/api_samples/os-volumes/os-volumes-post-req.json b/doc/api_samples/os-volumes/os-volumes-post-req.json index bc8d75a9a753..06a16140abe0 100644 --- a/doc/api_samples/os-volumes/os-volumes-post-req.json +++ b/doc/api_samples/os-volumes/os-volumes-post-req.json @@ -1,6 +1,6 @@ { "volume": { - "availability_zone": "zone1:host1", + "availability_zone": "dublin", "display_name": "Volume Name", "display_description": "Volume Description", "size": 100 diff --git a/doc/api_samples/os-volumes/os-volumes-post-resp.json b/doc/api_samples/os-volumes/os-volumes-post-resp.json index ba3795a0bb5e..b5c4a3cada79 100644 --- a/doc/api_samples/os-volumes/os-volumes-post-resp.json +++ b/doc/api_samples/os-volumes/os-volumes-post-resp.json @@ -8,7 +8,7 @@ "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "2013-02-18T14:51:17.970024", "displayDescription": "Volume Description", "displayName": "Volume Name", @@ -17,6 +17,6 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } -} \ No newline at end of file +} diff --git a/doc/api_samples/servers/v2.100/server-action-rebuild.json b/doc/api_samples/servers/v2.100/server-action-rebuild.json new file mode 100644 index 000000000000..3bea3dd5e2f6 --- /dev/null +++ b/doc/api_samples/servers/v2.100/server-action-rebuild.json @@ -0,0 +1,15 @@ +{ + "rebuild" : { + "accessIPv4" : "1.2.3.4", + "accessIPv6" : "80fe::", + "OS-DCF:diskConfig": "AUTO", + "imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b", + "name" : "foobar", + "adminPass" : "seekr3t", + "hostname": "updated-hostname.example.com", + "metadata" : { + "meta_var" : "meta_val" + }, + "user_data": "ZWNobyAiaGVsbG8gd29ybGQi" + } +} \ No newline at end of file diff --git a/doc/api_samples/servers/v2.100/server-create-req.json b/doc/api_samples/servers/v2.100/server-create-req.json new file mode 100644 index 000000000000..970aeee36aee --- /dev/null +++ b/doc/api_samples/servers/v2.100/server-create-req.json @@ -0,0 +1,25 @@ +{ + "server" : { + "accessIPv4": "1.2.3.4", + "accessIPv6": "80fe::", + "name" : "new-server-test", + "imageRef" : "70a599e0-31e7-49b7-b260-868f441e862b", + "flavorRef" : "1", + "OS-DCF:diskConfig": "AUTO", + "availability_zone": "us-west", + "metadata" : { + "My Server Name" : "Apache1" + }, + "security_groups": [ + { + "name": "default" + } + ], + "user_data" : "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==", + "networks": "auto", + "hostname": "new-server-test" + }, + "OS-SCH-HNT:scheduler_hints": { + "same_host": "48e6a9f6-30af-47e0-bc04-acaed113bb4e" + } +} \ No newline at end of file diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshot-create-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshot-create-resp.json.tpl index 6153e8140e60..6a20737f04b1 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshot-create-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshot-create-resp.json.tpl @@ -3,7 +3,7 @@ "createdAt": "%(strtime)s", "displayDescription": "%(description)s", "displayName": "%(snapshot_name)s", - "id": 100, + "id": "%(uuid)s", "size": 100, "status": "available", "volumeId": "%(uuid)s" diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-detail-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-detail-resp.json.tpl index 1b509d54f880..c1475108de8e 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-detail-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-detail-resp.json.tpl @@ -4,28 +4,28 @@ "createdAt": "%(strtime)s", "displayDescription": "Default description", "displayName": "Default name", - "id": 100, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" }, { "createdAt": "%(strtime)s", "displayDescription": "Default description", "displayName": "Default name", - "id": 101, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" }, { "createdAt": "%(strtime)s", "displayDescription": "Default description", "displayName": "Default name", - "id": 102, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" } ] } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-list-resp.json.tpl index c65d073ad768..008a760749d0 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-list-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-list-resp.json.tpl @@ -4,28 +4,28 @@ "createdAt": "%(strtime)s", "displayDescription": "%(text)s", "displayName": "%(text)s", - "id": 100, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" }, { "createdAt": "%(strtime)s", "displayDescription": "%(text)s", "displayName": "%(text)s", - "id": 101, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" }, { "createdAt": "%(strtime)s", "displayDescription": "%(text)s", "displayName": "%(text)s", - "id": 102, + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" } ] } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-show-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-show-resp.json.tpl index a9ab6240d620..6a20737f04b1 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-show-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-snapshots/snapshots-show-resp.json.tpl @@ -3,9 +3,9 @@ "createdAt": "%(strtime)s", "displayDescription": "%(description)s", "displayName": "%(snapshot_name)s", - "id": "100", + "id": "%(uuid)s", "size": 100, "status": "available", - "volumeId": 12 + "volumeId": "%(uuid)s" } } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-detail-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-detail-resp.json.tpl index 82a63eda5f27..77396181563a 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-detail-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-detail-resp.json.tpl @@ -9,7 +9,7 @@ "volumeId": "%(uuid)s" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "%(strtime)s", "displayDescription": "%(volume_desc)s", "displayName": "%(volume_name)s", @@ -18,7 +18,7 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } ] } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-get-resp.json.tpl index 84bfdd2a5b2d..b55d588724dd 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-get-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-get-resp.json.tpl @@ -8,7 +8,7 @@ "volumeId": "%(uuid)s" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "%(strtime)s", "displayDescription": "%(volume_desc)s", "displayName": "%(volume_name)s", @@ -17,6 +17,6 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-index-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-index-resp.json.tpl index 82a63eda5f27..77396181563a 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-index-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-index-resp.json.tpl @@ -9,7 +9,7 @@ "volumeId": "%(uuid)s" } ], - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "createdAt": "%(strtime)s", "displayDescription": "%(volume_desc)s", "displayName": "%(volume_name)s", @@ -18,7 +18,7 @@ "size": 100, "snapshotId": null, "status": "in-use", - "volumeType": "Backup" + "volumeType": "vol_type_name" } ] } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-req.json.tpl index 33e9a689444c..d25edc33668b 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-req.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-req.json.tpl @@ -1,6 +1,6 @@ { "volume": { - "availability_zone": "zone1:host1", + "availability_zone": "dublin", "display_name": "%(volume_name)s", "display_description": "%(volume_desc)s", "size": 100 diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-resp.json.tpl index d13ce20cc388..599148d531e9 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-volumes/os-volumes-post-resp.json.tpl @@ -2,7 +2,7 @@ "volume": { "status": "in-use", "displayDescription": "%(volume_desc)s", - "availabilityZone": "zone1:host1", + "availabilityZone": "dublin", "displayName": "%(volume_name)s", "attachments": [ { "device": "/", @@ -11,7 +11,7 @@ "volumeId": "%(uuid)s" } ], - "volumeType": "Backup", + "volumeType": "vol_type_name", "snapshotId": null, "metadata": {}, "id": "%(uuid)s", diff --git a/nova/tests/functional/api_sample_tests/test_snapshots.py b/nova/tests/functional/api_sample_tests/test_snapshots.py index 472a57147c99..a328497e3e8d 100644 --- a/nova/tests/functional/api_sample_tests/test_snapshots.py +++ b/nova/tests/functional/api_sample_tests/test_snapshots.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_utils.fixture import uuidsentinel as uuids + from nova.tests.functional.api_sample_tests import api_sample_base from nova.tests.unit.api.openstack import fakes @@ -54,7 +56,7 @@ class SnapshotsSampleJsonTests(api_sample_base.ApiSampleTestBaseV21): def test_snapshots_delete(self): self._create_snapshot() - response = self._do_delete('os-snapshots/100') + response = self._do_delete(f'os-snapshots/{uuids.snapshot}') self.assertEqual(202, response.status_code) self.assertEqual('', response.text) @@ -67,7 +69,7 @@ class SnapshotsSampleJsonTests(api_sample_base.ApiSampleTestBaseV21): self._verify_response('snapshots-list-resp', {}, response, 200) def test_snapshots_show(self): - response = self._do_get('os-snapshots/100') + response = self._do_get(f'os-snapshots/{uuids.snapshot}') subs = { 'snapshot_name': 'Default name', 'description': 'Default description' diff --git a/nova/tests/functional/api_sample_tests/test_volumes.py b/nova/tests/functional/api_sample_tests/test_volumes.py index 1c9ab80f16fa..895e83fe938b 100644 --- a/nova/tests/functional/api_sample_tests/test_volumes.py +++ b/nova/tests/functional/api_sample_tests/test_volumes.py @@ -13,62 +13,12 @@ # License for the specific language governing permissions and limitations # under the License. -import datetime +from oslo_utils.fixture import uuidsentinel as uuids from nova.tests.functional.api_sample_tests import test_servers from nova.tests.unit.api.openstack import fakes -def _get_volume_id(): - return 'a26887c6-c47b-4654-abb5-dfadf7d3f803' - - -def _stub_volume(id, displayname="Volume Name", - displaydesc="Volume Description", size=100): - volume = { - 'id': id, - 'size': size, - 'availability_zone': 'zone1:host1', - 'status': 'in-use', - 'attach_status': 'attached', - 'name': 'vol name', - 'display_name': displayname, - 'display_description': displaydesc, - 'created_at': datetime.datetime(2008, 12, 1, 11, 1, 55), - 'snapshot_id': None, - 'volume_type_id': 'fakevoltype', - 'volume_metadata': [], - 'volume_type': {'name': 'Backup'}, - 'multiattach': False, - 'attachments': {'3912f2b4-c5ba-4aec-9165-872876fe202e': - {'mountpoint': '/', - 'attachment_id': - 'a26887c6-c47b-4654-abb5-dfadf7d3f803' - } - } - } - return volume - - -def _stub_volume_get(stub_self, context, volume_id): - return _stub_volume(volume_id) - - -def _stub_volume_delete(stub_self, context, *args, **param): - pass - - -def _stub_volume_get_all(stub_self, context, search_opts=None): - id = _get_volume_id() - return [_stub_volume(id)] - - -def _stub_volume_create(stub_self, context, size, name, description, - snapshot, **param): - id = _get_volume_id() - return _stub_volume(id) - - class VolumesSampleJsonTest(test_servers.ServersSampleBase): sample_dir = "os-volumes" @@ -76,37 +26,36 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): super().setUp() fakes.stub_out_networking(self) - self.stub_out("nova.volume.cinder.API.delete", - _stub_volume_delete) - self.stub_out("nova.volume.cinder.API.get", _stub_volume_get) - self.stub_out("nova.volume.cinder.API.get_all", - _stub_volume_get_all) + self.stub_out( + "nova.volume.cinder.API.delete", fakes.stub_volume_delete) + self.stub_out("nova.volume.cinder.API.get", fakes.stub_volume_get) + self.stub_out( + "nova.volume.cinder.API.get_all", fakes.stub_volume_get_all) + self.stub_out( + "nova.volume.cinder.API.create", fakes.stub_volume_create) def _post_volume(self): subs_req = { - 'volume_name': "Volume Name", - 'volume_desc': "Volume Description", + 'volume_name': "Volume Name", + 'volume_desc': "Volume Description", } - self.stub_out("nova.volume.cinder.API.create", - _stub_volume_create) response = self._do_post('os-volumes', 'os-volumes-post-req', subs_req) self._verify_response('os-volumes-post-resp', subs_req, response, 200) def test_volumes_show(self): subs = { - 'volume_name': "Volume Name", - 'volume_desc': "Volume Description", + 'volume_name': "Volume Name", + 'volume_desc': "Volume Description", } - vol_id = _get_volume_id() - response = self._do_get('os-volumes/%s' % vol_id) + response = self._do_get(f'os-volumes/{uuids.volume}') self._verify_response('os-volumes-get-resp', subs, response, 200) def test_volumes_index(self): subs = { - 'volume_name': "Volume Name", - 'volume_desc': "Volume Description", + 'volume_name': "Volume Name", + 'volume_desc': "Volume Description", } response = self._do_get('os-volumes') self._verify_response('os-volumes-index-resp', subs, response, 200) @@ -115,8 +64,8 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): # For now, index and detail are the same. # See the volumes api subs = { - 'volume_name': "Volume Name", - 'volume_desc': "Volume Description", + 'volume_name': "Volume Name", + 'volume_desc': "Volume Description", } response = self._do_get('os-volumes/detail') self._verify_response('os-volumes-detail-resp', subs, response, 200) @@ -126,7 +75,6 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): def test_volumes_delete(self): self._post_volume() - vol_id = _get_volume_id() - response = self._do_delete('os-volumes/%s' % vol_id) + response = self._do_delete(f'os-volumes/{uuids.volume}') self.assertEqual(202, response.status_code) self.assertEqual('', response.text) diff --git a/nova/tests/unit/api/openstack/compute/test_snapshots.py b/nova/tests/unit/api/openstack/compute/test_snapshots.py index b493187e0b1d..c26f064c5afd 100644 --- a/nova/tests/unit/api/openstack/compute/test_snapshots.py +++ b/nova/tests/unit/api/openstack/compute/test_snapshots.py @@ -15,6 +15,7 @@ from unittest import mock +from oslo_utils.fixture import uuidsentinel as uuids import webob from nova.api.openstack.compute import snapshots @@ -23,11 +24,8 @@ from nova import test from nova.tests.unit.api.openstack import fakes from nova.volume import cinder -FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - class SnapshotApiTestV21(test.NoDBTestCase): - def setUp(self): super().setUp() fakes.stub_out_networking(self) @@ -46,7 +44,7 @@ class SnapshotApiTestV21(test.NoDBTestCase): self.req = fakes.HTTPRequest.blank('') def _test_snapshot_create(self, force): - snapshot = {"volume_id": '12', + snapshot = {"volume_id": uuids.volume, "force": force, "display_name": "Snapshot Test Name", "display_description": "Snapshot Test Desc"} @@ -69,8 +67,9 @@ class SnapshotApiTestV21(test.NoDBTestCase): def test_snapshot_create_invalid_force_param(self): body = {'snapshot': {'volume_id': '1', 'force': '**&&^^%%$$##@@'}} - self.assertRaises(exception.ValidationError, - self.controller.create, self.req, body=body) + self.assertRaises( + exception.ValidationError, + self.controller.create, self.req, body=body) def test_create_no_body(self): self.assertRaises( @@ -90,37 +89,29 @@ class SnapshotApiTestV21(test.NoDBTestCase): self.controller.create, self.req, body=body) def test_snapshot_delete(self): - snapshot_id = '123' - delete = self.controller.delete - result = delete(self.req, snapshot_id) + self.controller.delete(self.req, uuids.snapshot) - # NOTE: on v2.1, http status code is set as wsgi_codes of API - # method instead of status_int in a response object. - if isinstance(self.controller, snapshots.SnapshotController): - status_int = delete.wsgi_codes(self.req) - else: - status_int = result.status_int + status_int = self.controller.delete.wsgi_codes(self.req) self.assertEqual(202, status_int) @mock.patch.object(cinder.API, 'delete_snapshot', - side_effect=exception.SnapshotNotFound(snapshot_id=FAKE_UUID)) - def test_delete_snapshot_not_exists(self, mock_mr): - self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, - self.req, FAKE_UUID) - - def test_snapshot_delete_invalid_id(self): - self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, - self.req, '-1') + side_effect=exception.SnapshotNotFound(snapshot_id=uuids.missing)) + def test_snapshot_delete_not_exists(self, mock_mr): + self.assertRaises( + webob.exc.HTTPNotFound, self.controller.delete, + self.req, uuids.missing) def test_snapshot_show(self): - snapshot_id = '123' - resp_dict = self.controller.show(self.req, snapshot_id) + resp_dict = self.controller.show(self.req, uuids.snapshot) self.assertIn('snapshot', resp_dict) - self.assertEqual(str(snapshot_id), resp_dict['snapshot']['id']) + self.assertEqual(uuids.snapshot, resp_dict['snapshot']['id']) - def test_snapshot_show_invalid_id(self): - self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, - self.req, '-1') + @mock.patch.object(cinder.API, 'get_snapshot', + side_effect=exception.SnapshotNotFound(snapshot_id=uuids.missing)) + def test_snapshot_show_not_exists(self, mock_mr): + self.assertRaises( + webob.exc.HTTPNotFound, self.controller.show, + self.req, uuids.missing) def test_snapshot_detail(self): resp_dict = self.controller.detail(self.req) @@ -129,7 +120,7 @@ class SnapshotApiTestV21(test.NoDBTestCase): self.assertEqual(3, len(resp_snapshots)) resp_snapshot = resp_snapshots.pop() - self.assertEqual(102, resp_snapshot['id']) + self.assertEqual(uuids.snapshot_c, resp_snapshot['id']) def test_snapshot_detail_offset_and_limit(self): path = '/v2.1/os-snapshots/detail?offset=1&limit=1' @@ -140,7 +131,7 @@ class SnapshotApiTestV21(test.NoDBTestCase): self.assertEqual(1, len(resp_snapshots)) resp_snapshot = resp_snapshots.pop() - self.assertEqual(101, resp_snapshot['id']) + self.assertEqual(uuids.snapshot_b, resp_snapshot['id']) def test_snapshot_index(self): resp_dict = self.controller.index(self.req) @@ -246,9 +237,9 @@ class TestSnapshotAPIDeprecation(test.NoDBTestCase): def test_all_apis_return_not_found(self): self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.show, self.req, fakes.FAKE_UUID) + self.controller.show, self.req, uuids.snapshot_id) self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.delete, self.req, fakes.FAKE_UUID) + self.controller.delete, self.req, uuids.snapshot_id) self.assertRaises(exception.VersionNotFoundForAPIMethod, self.controller.index, self.req) self.assertRaises(exception.VersionNotFoundForAPIMethod, diff --git a/nova/tests/unit/api/openstack/compute/test_volume_attachments.py b/nova/tests/unit/api/openstack/compute/test_volume_attachments.py index 5ce1bceee21c..9d189be5f44e 100644 --- a/nova/tests/unit/api/openstack/compute/test_volume_attachments.py +++ b/nova/tests/unit/api/openstack/compute/test_volume_attachments.py @@ -98,7 +98,6 @@ def fake_bdm_get_by_volume_and_instance(cls, ctxt, volume_id, instance_uuid): class VolumeAttachTestsV21(test.NoDBTestCase): - validation_error = exception.ValidationError microversion = '2.1' _prefix = '/servers/id/os-volume_attachments' @@ -367,7 +366,7 @@ class VolumeAttachTestsV21(test.NoDBTestCase): 'volumeId': 'TESTVOLUME', } } - self.assertRaises(self.validation_error, self.controller.create, + self.assertRaises(exception.ValidationError, self.controller.create, self.req, FAKE_UUID, body=body) @mock.patch.object(compute_api.API, 'attach_volume', @@ -397,7 +396,7 @@ class VolumeAttachTestsV21(test.NoDBTestCase): } } - self.assertRaises(self.validation_error, self.controller.create, + self.assertRaises(exception.ValidationError, self.controller.create, self.req, FAKE_UUID, body=body) def test_attach_volume_with_extra_arg(self): @@ -407,7 +406,7 @@ class VolumeAttachTestsV21(test.NoDBTestCase): 'device': '/dev/fake', 'extra': 'extra_arg'}} - self.assertRaises(self.validation_error, self.controller.create, + self.assertRaises(exception.ValidationError, self.controller.create, self.req, FAKE_UUID, body=body) @mock.patch.object(compute_api.API, 'attach_volume') @@ -490,7 +489,7 @@ class VolumeAttachTestsV21(test.NoDBTestCase): def test_swap_volume_without_volumeId(self): body = {'volumeAttachment': {'device': '/dev/fake'}} - self.assertRaises(self.validation_error, + self.assertRaises(exception.ValidationError, self._test_swap, self.controller, body=body) @@ -499,7 +498,7 @@ class VolumeAttachTestsV21(test.NoDBTestCase): body = {'volumeAttachment': {'volumeId': FAKE_UUID_A, 'device': '/dev/fake'}} - self.assertRaises(self.validation_error, + self.assertRaises(exception.ValidationError, self._test_swap, self.controller, body=body) @@ -587,7 +586,6 @@ class VolumeAttachTestsV21(test.NoDBTestCase): class VolumeAttachTestsV249(test.NoDBTestCase): - validation_error = exception.ValidationError def setUp(self): super().setUp() @@ -617,7 +615,7 @@ class VolumeAttachTestsV249(test.NoDBTestCase): self.assertRaises(exception.ValidationError, self.controller.create, self.req, FAKE_UUID, body=body) - @mock.patch('nova.compute.api.API.attach_volume') + @mock.patch('nova.compute.api.API.attach_volume', return_value='/dev/fake') @mock.patch('nova.compute.api.API.get', fake_get_instance) def test_tagged_volume_attach_valid_tag(self, _): body = {'volumeAttachment': {'volumeId': FAKE_UUID_A, @@ -722,7 +720,7 @@ class VolumeAttachTestsV275(VolumeAttachTestsV21): def test_list_with_additional_filter(self): req = self._build_request( '?limit=1&additional=something') - self.assertRaises(self.validation_error, self.controller.index, + self.assertRaises(exception.ValidationError, self.controller.index, req, FAKE_UUID) @@ -907,7 +905,7 @@ class VolumeAttachTestsV285(VolumeAttachTestsV279): 'device': '/dev/fake0', 'notathing': 'foo'}} - self.assertRaises(self.validation_error, + self.assertRaises(exception.ValidationError, self._test_swap, self.controller, body=body) @@ -1256,7 +1254,7 @@ class VolumeAttachTestsV289(VolumeAttachTestsV285): 'volumeId': FAKE_UUID_A, 'tag': None, 'delete_on_termination': False, - 'attachment_id': None, + 'attachment_id': uuids.attachment_id, 'bdm_uuid': uuids.bdm, } } diff --git a/nova/tests/unit/api/openstack/compute/test_volumes.py b/nova/tests/unit/api/openstack/compute/test_volumes.py index 974884fc23e8..44b22ccf745a 100644 --- a/nova/tests/unit/api/openstack/compute/test_volumes.py +++ b/nova/tests/unit/api/openstack/compute/test_volumes.py @@ -31,9 +31,6 @@ from nova.volume import cinder CONF = nova.conf.CONF -FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' -IMAGE_UUID = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' - class BootFromVolumeTest(test.TestCase): @@ -56,11 +53,11 @@ class BootFromVolumeTest(test.TestCase): resv_id = None return ([{'id': 1, 'display_name': 'test_server', - 'uuid': FAKE_UUID, + 'uuid': uuids.server, 'flavor': flavor, 'access_ip_v4': '1.2.3.4', 'access_ip_v6': 'fead::1234', - 'image_ref': IMAGE_UUID, + 'image_ref': uuids.image, 'user_id': 'fake', 'project_id': fakes.FAKE_PROJECT_ID, 'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0), @@ -72,7 +69,7 @@ class BootFromVolumeTest(test.TestCase): def test_create_root_volume(self): body = dict(server=dict( - name='test_server', imageRef=IMAGE_UUID, + name='test_server', imageRef=uuids.image, flavorRef=2, min_count=1, max_count=1, block_device_mapping=[dict( volume_id='ca9fe3f5-cede-43cb-8050-1672acabe348', @@ -88,7 +85,7 @@ class BootFromVolumeTest(test.TestCase): res = req.get_response(fakes.wsgi_app_v21()) self.assertEqual(202, res.status_int) server = jsonutils.loads(res.body)['server'] - self.assertEqual(FAKE_UUID, server['id']) + self.assertEqual(uuids.server, server['id']) self.assertEqual(CONF.password_length, len(server['adminPass'])) self.assertEqual(1, len(self._block_device_mapping_seen)) self.assertTrue(self._legacy_bdm_seen) @@ -99,7 +96,7 @@ class BootFromVolumeTest(test.TestCase): def test_create_root_volume_bdm_v2(self): body = dict(server=dict( - name='test_server', imageRef=IMAGE_UUID, + name='test_server', imageRef=uuids.image, flavorRef=2, min_count=1, max_count=1, block_device_mapping_v2=[dict( source_type='volume', @@ -117,7 +114,7 @@ class BootFromVolumeTest(test.TestCase): res = req.get_response(fakes.wsgi_app_v21()) self.assertEqual(202, res.status_int) server = jsonutils.loads(res.body)['server'] - self.assertEqual(FAKE_UUID, server['id']) + self.assertEqual(uuids.server, server['id']) self.assertEqual(CONF.password_length, len(server['adminPass'])) self.assertEqual(1, len(self._block_device_mapping_seen)) self.assertFalse(self._legacy_bdm_seen) @@ -132,13 +129,13 @@ class VolumeApiTestV21(test.NoDBTestCase): super().setUp() fakes.stub_out_networking(self) - self.stub_out('nova.volume.cinder.API.create', - fakes.stub_volume_create) - self.stub_out('nova.volume.cinder.API.delete', - lambda self, context, volume_id: None) + self.stub_out( + 'nova.volume.cinder.API.create', fakes.stub_volume_create) + self.stub_out( + 'nova.volume.cinder.API.delete', fakes.stub_volume_delete) self.stub_out('nova.volume.cinder.API.get', fakes.stub_volume_get) - self.stub_out('nova.volume.cinder.API.get_all', - fakes.stub_volume_get_all) + self.stub_out( + 'nova.volume.cinder.API.get_all', fakes.stub_volume_get_all) self.controller = volumes_v21.VolumeController() self.req = fakes.HTTPRequest.blank('') @@ -147,7 +144,7 @@ class VolumeApiTestV21(test.NoDBTestCase): vol = {"size": 100, "display_name": "Volume Test Name", "display_description": "Volume Test Desc", - "availability_zone": "zone1:host1"} + "availability_zone": "dublin"} body = {"volume": vol} resp = self.controller.create(self.req, body=body).obj @@ -168,7 +165,7 @@ class VolumeApiTestV21(test.NoDBTestCase): vol = {"size": '10', "display_name": "Volume Test Name", "display_description": "Volume Test Desc", - "availability_zone": "zone1:host1"} + "availability_zone": "dublin"} body = {"volume": vol} self.assertRaises(api_exc, @@ -176,7 +173,7 @@ class VolumeApiTestV21(test.NoDBTestCase): body=body) mock_create.assert_called_once_with( mock.ANY, '10', 'Volume Test Name', - 'Volume Test Desc', availability_zone='zone1:host1', + 'Volume Test Desc', availability_zone='dublin', metadata=None, snapshot=None, volume_type=None) @mock.patch.object(cinder.API, 'get_snapshot') @@ -335,9 +332,9 @@ class TestVolumesAPIDeprecation(test.NoDBTestCase): def test_all_apis_return_not_found(self): self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.show, self.req, fakes.FAKE_UUID) + self.controller.show, self.req, uuids.volume) self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.delete, self.req, fakes.FAKE_UUID) + self.controller.delete, self.req, uuids.volume) self.assertRaises(exception.VersionNotFoundForAPIMethod, self.controller.index, self.req) self.assertRaises(exception.VersionNotFoundForAPIMethod, diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index bc815b6ae28f..d6c9541c4de8 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -43,11 +43,9 @@ from nova.tests.unit import fake_block_device from nova.tests.unit.objects import test_keypair from nova import utils - CONF = nova.conf.CONF QUOTAS = quota.QUOTAS - FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' FAKE_PROJECT_ID = '6a6a9c9eee154e9cb8cec487b98d36ab' FAKE_USER_ID = '5fae60f5cf4642609ddd31f71748beac' @@ -575,36 +573,40 @@ def stub_instance_obj(ctxt, *args, **kwargs): def stub_volume(id, **kwargs): + # volumes IDs should be UUIDs + assert uuidutils.is_uuid_like(id), f'expected UUID, got {id}' volume = { 'id': id, 'user_id': 'fakeuser', 'project_id': 'fakeproject', 'host': 'fakehost', - 'size': 1, - 'availability_zone': 'fakeaz', - 'status': 'fakestatus', + 'size': 100, + 'availability_zone': 'dublin', + 'status': 'in-use', 'attach_status': 'attached', 'name': 'vol name', - 'display_name': 'displayname', - 'display_description': 'displaydesc', - 'created_at': datetime.datetime(1999, 1, 1, 1, 1, 1), + 'display_name': 'Volume Name', + 'display_description': 'Volume Description', + 'created_at': datetime.datetime(2008, 12, 1, 11, 1, 55), 'snapshot_id': None, 'volume_type_id': 'fakevoltype', 'volume_metadata': [], 'volume_type': {'name': 'vol_type_name'}, 'multiattach': False, - 'attachments': {'fakeuuid': {'mountpoint': '/'}, - 'fakeuuid2': {'mountpoint': '/dev/sdb'} - } - } - + 'attachments': { + uuids.server: { + 'mountpoint': '/', + 'attachment_id': 'a26887c6-c47b-4654-abb5-dfadf7d3f803', + } + } + } volume.update(kwargs) return volume def stub_volume_create(self, context, size, name, description, snapshot, **param): - vol = stub_volume('1') + vol = stub_volume(uuids.volume) vol['size'] = size vol['display_name'] = name vol['display_description'] = description @@ -612,10 +614,14 @@ def stub_volume_create(self, context, size, name, description, snapshot, vol['snapshot_id'] = snapshot['id'] except (KeyError, TypeError): vol['snapshot_id'] = None - vol['availability_zone'] = param.get('availability_zone', 'fakeaz') + vol['availability_zone'] = param.get('availability_zone', 'dublin') return vol +def stub_volume_delete(self, context, id): + assert uuidutils.is_uuid_like(id) + + def stub_volume_update(self, context, *args, **param): pass @@ -625,9 +631,10 @@ def stub_volume_get(self, context, volume_id): def stub_volume_get_all(context, search_opts=None): - return [stub_volume(100, project_id='fake'), - stub_volume(101, project_id='superfake'), - stub_volume(102, project_id='superduperfake')] + return [ + stub_volume( + uuids.volume_a, project_id='ccbab0871dac4d598a4142f0583d94b2'), + ] def stub_volume_check_attach(self, context, *args, **param): @@ -635,24 +642,31 @@ def stub_volume_check_attach(self, context, *args, **param): def stub_snapshot(id, **kwargs): + # snapshot IDs should be UUIDs + assert uuidutils.is_uuid_like(id), f'expected UUID, got {id}' + + if 'volume_id' in kwargs: + assert uuidutils.is_uuid_like(kwargs['volume_id']) + snapshot = { 'id': id, - 'volume_id': 12, + 'volume_id': uuids.volume, 'status': 'available', 'volume_size': 100, 'created_at': timeutils.utcnow(), 'display_name': 'Default name', 'display_description': 'Default description', 'project_id': 'fake' - } + } snapshot.update(kwargs) return snapshot def stub_snapshot_create(self, context, volume_id, name, description): - return stub_snapshot(100, volume_id=volume_id, display_name=name, - display_description=description) + return stub_snapshot( + uuids.snapshot, volume_id=volume_id, display_name=name, + display_description=description) def stub_compute_volume_snapshot_create(self, context, volume_id, create_info): @@ -660,9 +674,9 @@ def stub_compute_volume_snapshot_create(self, context, volume_id, create_info): 'volumeId': volume_id}} -def stub_snapshot_delete(self, context, snapshot_id): - if snapshot_id == '-1': - raise exc.SnapshotNotFound(snapshot_id=snapshot_id) +def stub_snapshot_delete(self, context, id): + # snapshot IDs should be UUIDs + assert uuidutils.is_uuid_like(id), f'expected UUID, got {id}' def stub_compute_volume_snapshot_delete(self, context, volume_id, snapshot_id, @@ -670,16 +684,14 @@ def stub_compute_volume_snapshot_delete(self, context, volume_id, snapshot_id, pass -def stub_snapshot_get(self, context, snapshot_id): - if snapshot_id == '-1': - raise exc.SnapshotNotFound(snapshot_id=snapshot_id) - return stub_snapshot(snapshot_id) +def stub_snapshot_get(self, context, id): + return stub_snapshot(id) def stub_snapshot_get_all(self, context): - return [stub_snapshot(100, project_id='fake'), - stub_snapshot(101, project_id='superfake'), - stub_snapshot(102, project_id='superduperfake')] + return [stub_snapshot(uuids.snapshot_a, project_id='fake'), + stub_snapshot(uuids.snapshot_b, project_id='superfake'), + stub_snapshot(uuids.snapshot_c, project_id='superduperfake')] def stub_bdm_get_all_by_instance_uuids(context, instance_uuids, diff --git a/nova/tests/unit/fake_block_device.py b/nova/tests/unit/fake_block_device.py index 1a001723e4bb..a4410b276290 100644 --- a/nova/tests/unit/fake_block_device.py +++ b/nova/tests/unit/fake_block_device.py @@ -40,6 +40,7 @@ class FakeDbBlockDeviceDict(block_device.BlockDeviceDict): bdm_dict = bdm_dict or {} db_id = bdm_dict.pop('id', 1) db_uuid = bdm_dict.pop('uuid', uuids.bdm) + db_attachment_id = bdm_dict.get('attachment_id', None) instance_uuid = bdm_dict.pop('instance_uuid', uuids.fake) super(FakeDbBlockDeviceDict, self).__init__(bdm_dict=bdm_dict, @@ -50,7 +51,7 @@ class FakeDbBlockDeviceDict(block_device.BlockDeviceDict): if not anon: fake_db_fields['id'] = db_id fake_db_fields['uuid'] = db_uuid - fake_db_fields['attachment_id'] = None + fake_db_fields['attachment_id'] = db_attachment_id fake_db_fields['created_at'] = timeutils.utcnow() fake_db_fields['updated_at'] = timeutils.utcnow() self.update(fake_db_fields) diff --git a/nova/tests/unit/policies/test_snapshots.py b/nova/tests/unit/policies/test_snapshots.py index 901e97fbe6c9..bf6469455d34 100644 --- a/nova/tests/unit/policies/test_snapshots.py +++ b/nova/tests/unit/policies/test_snapshots.py @@ -21,6 +21,17 @@ from nova.tests.unit.api.openstack import fakes from nova.tests.unit.policies import base +fake_snapshot = { + 'created_at': '2024-11-26T18:20:21.000000', + 'display_name': 'foo', + 'display_description': None, + 'id': uuids.snapshot_id, + 'status': 'available', + 'volume_id': uuids.volume_id, + 'volume_size': 1, +} + + class SnapshotsPolicyTest(base.BasePolicyTest): """Test Snapshots APIs policies with all possible context. @@ -66,6 +77,7 @@ class SnapshotsPolicyTest(base.BasePolicyTest): @mock.patch('nova.volume.cinder.API.get_all_snapshots') def test_list_snapshots_policy(self, mock_get): + mock_get.return_value = [] rule_name = "os_compute_api:os-volumes:snapshots:list" self.common_policy_auth(self.project_reader_authorized_contexts, rule_name, self.snapshot_ctlr.index, @@ -73,6 +85,7 @@ class SnapshotsPolicyTest(base.BasePolicyTest): @mock.patch('nova.volume.cinder.API.get_all_snapshots') def test_list_detail_snapshots_policy(self, mock_get): + mock_get.return_value = [] rule_name = "os_compute_api:os-volumes:snapshots:detail" self.common_policy_auth(self.project_reader_authorized_contexts, rule_name, self.snapshot_ctlr.detail, @@ -80,6 +93,7 @@ class SnapshotsPolicyTest(base.BasePolicyTest): @mock.patch('nova.volume.cinder.API.get_snapshot') def test_show_snapshot_policy(self, mock_get): + mock_get.return_value = fake_snapshot rule_name = "os_compute_api:os-volumes:snapshots:show" self.common_policy_auth(self.project_reader_authorized_contexts, rule_name, self.snapshot_ctlr.show, @@ -87,6 +101,7 @@ class SnapshotsPolicyTest(base.BasePolicyTest): @mock.patch('nova.volume.cinder.API.create_snapshot') def test_create_snapshot_policy(self, mock_create): + mock_create.return_value = fake_snapshot rule_name = "os_compute_api:os-volumes:snapshots:create" body = {"snapshot": {"volume_id": uuids.fake_id}} self.common_policy_auth(self.project_member_authorized_contexts, diff --git a/nova/tests/unit/policies/test_volume_attachments.py b/nova/tests/unit/policies/test_volume_attachments.py index 8696f7b5084f..38d69e45580a 100644 --- a/nova/tests/unit/policies/test_volume_attachments.py +++ b/nova/tests/unit/policies/test_volume_attachments.py @@ -140,6 +140,7 @@ class VolumeAttachPolicyTest(base.BasePolicyTest): @mock.patch('nova.compute.api.API.attach_volume') def test_create_volume_attach_policy(self, mock_attach_volume): + mock_attach_volume.return_value = '/dev/sdb' rule_name = self.policy_root % "create" body = {'volumeAttachment': {'volumeId': FAKE_UUID_B, 'device': '/dev/fake'}} diff --git a/nova/tests/unit/policies/test_volumes.py b/nova/tests/unit/policies/test_volumes.py index 8459322f73c3..fccf3032e5a7 100644 --- a/nova/tests/unit/policies/test_volumes.py +++ b/nova/tests/unit/policies/test_volumes.py @@ -81,20 +81,42 @@ class VolumesPolicyTest(base.BasePolicyTest): @mock.patch('nova.volume.cinder.API.get') def test_show_volume_policy(self, mock_get): + mock_get.return_value = { + 'attach_status': 'detached', + 'availability_zone': 'nova', + 'created_at': '2024-11-26T18:20:21.000000', + 'display_name': 'foo', + 'display_description': None, + 'id': uuids.volume_id, + 'size': 1, + 'snapshot_id': None, + 'status': 'available', + 'volume_type_id': uuids.volume_type_id, + } rule_name = "os_compute_api:os-volumes:show" self.common_policy_auth(self.project_reader_authorized_contexts, rule_name, self.controller.show, self.req, uuids.fake_id) - @mock.patch('nova.api.openstack.compute.volumes.' - '_translate_volume_detail_view') @mock.patch('nova.volume.cinder.API.create') - def test_create_volumes_policy(self, mock_create, mock_view): + def test_create_volumes_policy(self, mock_create): + mock_create.return_value = { + 'attach_status': 'detached', + 'availability_zone': 'nova', + 'created_at': '2024-11-26T18:20:21.000000', + 'display_name': 'foo', + 'display_description': None, + 'id': uuids.volume_id, + 'size': 1, + 'snapshot_id': None, + 'status': 'available', + 'volume_type_id': uuids.volume_type_id, + } rule_name = "os_compute_api:os-volumes:create" body = {"volume": {"size": 100, "display_name": "Volume Test Name", "display_description": "Volume Test Desc", - "availability_zone": "zone1:host1"}} + "availability_zone": "dublin"}} self.common_policy_auth(self.project_member_authorized_contexts, rule_name, self.controller.create, self.req, body=body)