Skip to content

Commit 26d50be

Browse files
zhiyong.daiDean Troyer
authored andcommitted
Support "--no-property" option in volume snapshot set
Supporting "--no-property" option will apply user a convenient way to clean all properties of volume snapshot in a short command, and this kind of behavior is the recommended way to devref. The patch adds "--no-property" option in "volume snapshot set" command, and update related test cases and devref document. Change-Id: I5f10cc2b5814553699920c4343995b2e11416e4e Implements: blueprint allow-overwrite-set-options
1 parent d5745ea commit 26d50be

8 files changed

Lines changed: 357 additions & 59 deletions

File tree

doc/source/command-objects/volume-snapshot.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ Set volume snapshot properties
133133
openstack volume snapshot set
134134
[--name <name>]
135135
[--description <description>]
136+
[--no-property]
136137
[--property <key=value> [...] ]
137138
[--state <state>]
138139
<snapshot>
@@ -145,6 +146,12 @@ Set volume snapshot properties
145146
146147
New snapshot description
147148
149+
.. option:: --no-property
150+
151+
Remove all properties from :ref:`\<snapshot\> <volume_snapshot_set-snapshot>`
152+
(specify both :option:`--no-property` and :option:`--property` to
153+
remove the current properties before setting new properties.)
154+
148155
.. option:: --property <key=value>
149156
150157
Property to add or modify for this snapshot (repeat option to set multiple properties)

openstackclient/tests/functional/volume/v1/test_snapshot.py

Lines changed: 206 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13+
import json
1314
import time
1415
import uuid
1516

@@ -20,69 +21,230 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
2021
"""Functional tests for volume snapshot. """
2122

2223
VOLLY = uuid.uuid4().hex
23-
NAME = uuid.uuid4().hex
24-
OTHER_NAME = uuid.uuid4().hex
25-
HEADERS = ['"Name"']
2624

2725
@classmethod
2826
def wait_for_status(cls, command, status, tries):
2927
opts = cls.get_opts(['status'])
3028
for attempt in range(tries):
3129
time.sleep(1)
3230
raw_output = cls.openstack(command + opts)
33-
if (raw_output == status):
31+
if (raw_output.rstrip() == status):
3432
return
3533
cls.assertOutput(status, raw_output)
3634

3735
@classmethod
3836
def setUpClass(cls):
3937
super(VolumeSnapshotTests, cls).setUpClass()
40-
cls.openstack('volume create --size 1 ' + cls.VOLLY)
41-
cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3)
42-
opts = cls.get_opts(['status'])
43-
raw_output = cls.openstack('volume snapshot create --volume ' +
44-
cls.VOLLY + ' ' + cls.NAME + opts)
45-
cls.assertOutput('creating\n', raw_output)
46-
cls.wait_for_status(
47-
'volume snapshot show ' + cls.NAME, 'available\n', 3)
38+
# create a volume for all tests to create snapshot
39+
cmd_output = json.loads(cls.openstack(
40+
'volume create -f json ' +
41+
'--size 1 ' +
42+
cls.VOLLY
43+
))
44+
cls.wait_for_status('volume show ' + cls.VOLLY, 'available', 6)
45+
cls.VOLUME_ID = cmd_output['id']
4846

4947
@classmethod
5048
def tearDownClass(cls):
51-
# Rename test
52-
raw_output = cls.openstack(
53-
'volume snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME)
49+
cls.wait_for_status('volume show ' + cls.VOLLY, 'available', 6)
50+
raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
5451
cls.assertOutput('', raw_output)
55-
# Delete test
56-
raw_output_snapshot = cls.openstack(
57-
'volume snapshot delete ' + cls.OTHER_NAME)
58-
cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6)
59-
raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY)
60-
cls.assertOutput('', raw_output_snapshot)
61-
cls.assertOutput('', raw_output_volume)
62-
63-
def test_snapshot_list(self):
64-
opts = self.get_opts(self.HEADERS)
65-
raw_output = self.openstack('volume snapshot list' + opts)
66-
self.assertIn(self.NAME, raw_output)
67-
68-
def test_snapshot_set_unset_properties(self):
52+
53+
def test_volume_snapshot__delete(self):
54+
"""Test create, delete multiple"""
55+
name1 = uuid.uuid4().hex
56+
cmd_output = json.loads(self.openstack(
57+
'volume snapshot create -f json ' +
58+
name1 +
59+
' --volume ' + self.VOLLY
60+
))
61+
self.assertEqual(
62+
name1,
63+
cmd_output["display_name"],
64+
)
65+
66+
name2 = uuid.uuid4().hex
67+
cmd_output = json.loads(self.openstack(
68+
'volume snapshot create -f json ' +
69+
name2 +
70+
' --volume ' + self.VOLLY
71+
))
72+
self.assertEqual(
73+
name2,
74+
cmd_output["display_name"],
75+
)
76+
77+
self.wait_for_status(
78+
'volume snapshot show ' + name1, 'available', 6)
79+
self.wait_for_status(
80+
'volume snapshot show ' + name2, 'available', 6)
81+
82+
del_output = self.openstack(
83+
'volume snapshot delete ' + name1 + ' ' + name2)
84+
self.assertOutput('', del_output)
85+
86+
def test_volume_snapshot_list(self):
87+
"""Test create, list filter"""
88+
name1 = uuid.uuid4().hex
89+
cmd_output = json.loads(self.openstack(
90+
'volume snapshot create -f json ' +
91+
name1 +
92+
' --volume ' + self.VOLLY
93+
))
94+
self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
95+
self.assertEqual(
96+
name1,
97+
cmd_output["display_name"],
98+
)
99+
self.assertEqual(
100+
self.VOLUME_ID,
101+
cmd_output["volume_id"],
102+
)
103+
self.assertEqual(
104+
1,
105+
cmd_output["size"],
106+
)
107+
self.wait_for_status(
108+
'volume snapshot show ' + name1, 'available', 6)
109+
110+
name2 = uuid.uuid4().hex
111+
cmd_output = json.loads(self.openstack(
112+
'volume snapshot create -f json ' +
113+
name2 +
114+
' --volume ' + self.VOLLY
115+
))
116+
self.addCleanup(self.openstack, 'volume snapshot delete ' + name2)
117+
self.assertEqual(
118+
name2,
119+
cmd_output["display_name"],
120+
)
121+
self.assertEqual(
122+
self.VOLUME_ID,
123+
cmd_output["volume_id"],
124+
)
125+
self.assertEqual(
126+
1,
127+
cmd_output["size"],
128+
)
129+
self.wait_for_status(
130+
'volume snapshot show ' + name2, 'available', 6)
131+
132+
# Test list --long, --status
133+
cmd_output = json.loads(self.openstack(
134+
'volume snapshot list -f json ' +
135+
'--long ' +
136+
'--status error'
137+
))
138+
names = [x["Name"] for x in cmd_output]
139+
self.assertNotIn(name1, names)
140+
self.assertNotIn(name2, names)
141+
142+
# Test list --volume
143+
cmd_output = json.loads(self.openstack(
144+
'volume snapshot list -f json ' +
145+
'--volume ' + self.VOLLY
146+
))
147+
names = [x["Name"] for x in cmd_output]
148+
self.assertIn(name1, names)
149+
self.assertIn(name2, names)
150+
151+
# Test list --name
152+
cmd_output = json.loads(self.openstack(
153+
'volume snapshot list -f json ' +
154+
'--name ' + name1
155+
))
156+
names = [x["Name"] for x in cmd_output]
157+
self.assertIn(name1, names)
158+
self.assertNotIn(name2, names)
159+
160+
def test_snapshot_set(self):
161+
"""Test create, set, unset, show, delete volume snapshot"""
162+
name = uuid.uuid4().hex
163+
new_name = name + "_"
164+
cmd_output = json.loads(self.openstack(
165+
'volume snapshot create -f json ' +
166+
'--volume ' + self.VOLLY +
167+
' --description aaaa ' +
168+
name
169+
))
170+
self.addCleanup(self.openstack, 'volume snapshot delete ' + new_name)
171+
self.assertEqual(
172+
name,
173+
cmd_output["display_name"],
174+
)
175+
self.assertEqual(
176+
1,
177+
cmd_output["size"],
178+
)
179+
self.assertEqual(
180+
'aaaa',
181+
cmd_output["display_description"],
182+
)
183+
self.wait_for_status(
184+
'volume snapshot show ' + name, 'available', 6)
185+
186+
# Test volume snapshot set
69187
raw_output = self.openstack(
70-
'volume snapshot set --property a=b --property c=d ' + self.NAME)
71-
self.assertEqual("", raw_output)
72-
opts = self.get_opts(["properties"])
73-
raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
74-
self.assertEqual("a='b', c='d'\n", raw_output)
188+
'volume snapshot set ' +
189+
'--name ' + new_name +
190+
' --description bbbb ' +
191+
'--property Alpha=a ' +
192+
'--property Beta=b ' +
193+
name,
194+
)
195+
self.assertOutput('', raw_output)
196+
197+
# Show snapshot set result
198+
cmd_output = json.loads(self.openstack(
199+
'volume snapshot show -f json ' +
200+
new_name
201+
))
202+
self.assertEqual(
203+
new_name,
204+
cmd_output["display_name"],
205+
)
206+
self.assertEqual(
207+
1,
208+
cmd_output["size"],
209+
)
210+
self.assertEqual(
211+
'bbbb',
212+
cmd_output["display_description"],
213+
)
214+
self.assertEqual(
215+
"Alpha='a', Beta='b'",
216+
cmd_output["properties"],
217+
)
75218

219+
# Test volume unset
76220
raw_output = self.openstack(
77-
'volume snapshot unset --property a ' + self.NAME)
78-
self.assertEqual("", raw_output)
79-
raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
80-
self.assertEqual("c='d'\n", raw_output)
221+
'volume snapshot unset ' +
222+
'--property Alpha ' +
223+
new_name,
224+
)
225+
self.assertOutput('', raw_output)
226+
227+
cmd_output = json.loads(self.openstack(
228+
'volume snapshot show -f json ' +
229+
new_name
230+
))
231+
self.assertEqual(
232+
"Beta='b'",
233+
cmd_output["properties"],
234+
)
81235

82-
def test_snapshot_set_description(self):
236+
# Test volume snapshot set --no-property
83237
raw_output = self.openstack(
84-
'volume snapshot set --description backup ' + self.NAME)
85-
self.assertEqual("", raw_output)
86-
opts = self.get_opts(["display_description", "display_name"])
87-
raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
88-
self.assertEqual("backup\n" + self.NAME + "\n", raw_output)
238+
'volume snapshot set ' +
239+
'--no-property ' +
240+
new_name,
241+
)
242+
self.assertOutput('', raw_output)
243+
cmd_output = json.loads(self.openstack(
244+
'volume snapshot show -f json ' +
245+
new_name
246+
))
247+
self.assertNotIn(
248+
"Beta='b'",
249+
cmd_output["properties"],
250+
)

0 commit comments

Comments
 (0)