Set functional test environment
devstack-admin:
auth:
auth_url: http://-/identity/v3
username: "admin"
password: "admin"
project_domain_name: "default"
project_name: "admin"
user_domain_name: "default"
region_name: "RegionOne"
interface: "public"
auth_type: "password"
identity_api_version: 3
config 위치에 유의합니다. (~/.config/openstack/clouds.yaml)
확실히 설정하기 위해서 export OS* 또한 적용해주었습니다.
아래 설정을 하고 난 뒤에는 openstack 만으로도 명령어 수행이 가능합니다.
export OS_CLOUD=devstack_cinder
export OS_CLIENT_CONFIG_FILE=/c/Users/rladb/.config/openstack/clouds.yaml
Break down test_volume_snapshot.py
# 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.
import uuid
from openstackclient.tests.functional.volume.v3 import common
class VolumeSnapshotTests(common.BaseVolumeTests):
#[YS] common.BaseVolumeTests 공통 테스트 유틸리티를 제공한다.
"""Functional tests for volume snapshot."""
VOLLY = uuid.uuid4().hex
#[YS] 테스트에서 생성할 volume의 고유 이름을 저장하는 클래스 변수이다.
#[YS] 랜덤한 32자리 16진수 문자열 생성한다.
@classmethod
def setUpClass(cls):
#[YS] cls는 해당 클래스 자체 VolumeSnapshotTests를 가리킨다.
#[YS] 클래스 속성에 접근할 때 사용된다 ex) VOLLY, VOLUME_ID
super().setUpClass()
# create a volume for all tests to create snapshot
#[YS] 테스트 시작 시 클래스 단위로 1GB 볼륨을 생성한다.
cmd_output = cls.openstack(
'volume create ' + '--size 1 ' + cls.VOLLY,
parse_output=True,
)
cls.wait_for_status('volume', cls.VOLLY, 'available')
#[YS] volume이 available 상태가 될 때까지 대기
cls.VOLUME_ID = cmd_output['id']
#[YS] 생성된 volume id를 클래스 속성으로 지정한다.
@classmethod
def tearDownClass(cls):
#[YS] 테스트 종료 시 볼륨 삭제
try:
cls.wait_for_status('volume', cls.VOLLY, 'available')
raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
cls.assertOutput('', raw_output)
finally:
super().tearDownClass()
def test_volume_snapshot_delete(self):
"""Test create, delete multiple"""
name1 = uuid.uuid4().hex
#[YS] uuid 기반으로 스냅샷1 생성
cmd_output = self.openstack(
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
parse_output=True,
)
#[YS] 생성 후 생성 확인
self.assertEqual(
name1,
cmd_output["name"],
)
name2 = uuid.uuid4().hex
#[YS] uuid 기반으로 스냅샷2 생성
cmd_output = self.openstack(
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
parse_output=True,
)
self.assertEqual(
name2,
cmd_output["name"],
)
self.wait_for_status('volume snapshot', name1, 'available')
self.wait_for_status('volume snapshot', name2, 'available')
#[YS] available까지 대기
del_output = self.openstack(
'volume snapshot delete ' + name1 + ' ' + name2
)
#[YS] 2개 삭제
self.assertOutput('', del_output)
self.wait_for_delete('volume snapshot', name1)
self.wait_for_delete('volume snapshot', name2)
#[YS] 삭제 확인 >> volume/base.py import
def test_volume_snapshot_list(self):
"""Test create, list filter"""
name1 = uuid.uuid4().hex
#[YS] 스냅샷 생성
cmd_output = self.openstack(
'volume snapshot create ' + name1 + ' --volume ' + self.VOLLY,
parse_output=True,
)
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
#[YS] 자동 삭제 예약
self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
#[YS] 정보 같은지 확인
self.assertEqual(
name1,
cmd_output["name"],
)
self.assertEqual(
self.VOLUME_ID,
cmd_output["volume_id"],
)
self.assertEqual(
1,
cmd_output["size"],
)
self.wait_for_status('volume snapshot', name1, 'available')
name2 = uuid.uuid4().hex
cmd_output = self.openstack(
'volume snapshot create ' + name2 + ' --volume ' + self.VOLLY,
parse_output=True,
)
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
self.addCleanup(self.openstack, 'volume snapshot delete ' + name2)
self.assertEqual(
name2,
cmd_output["name"],
)
self.assertEqual(
self.VOLUME_ID,
cmd_output["volume_id"],
)
self.assertEqual(
1,
cmd_output["size"],
)
self.wait_for_status('volume snapshot', name2, 'available')
raw_output = self.openstack(
'volume snapshot set ' + '--state error ' + name2
)
self.assertOutput('', raw_output)
# Test list --long, --status
cmd_output = self.openstack(
'volume snapshot list ' + '--long ' + '--status error',
parse_output=True,
)
names = [x["Name"] for x in cmd_output]
self.assertNotIn(name1, names)
self.assertIn(name2, names)
# Test list --volume
cmd_output = self.openstack(
'volume snapshot list ' + '--volume ' + self.VOLLY,
parse_output=True,
)
names = [x["Name"] for x in cmd_output]
self.assertIn(name1, names)
self.assertIn(name2, names)
# Test list --name
cmd_output = self.openstack(
'volume snapshot list ' + '--name ' + name1,
parse_output=True,
)
names = [x["Name"] for x in cmd_output]
self.assertIn(name1, names)
self.assertNotIn(name2, names)
def test_volume_snapshot_set(self):
"""Test create, set, unset, show, delete volume snapshot"""
name = uuid.uuid4().hex
new_name = name + "_"
#[YS] 옵션 넣어서 생성
cmd_output = self.openstack(
'volume snapshot create '
+ '--volume '
+ self.VOLLY
+ ' --description aaaa '
+ '--property Alpha=a '
+ name,
parse_output=True,
)
#[YS] 삭제 예약
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
self.addCleanup(self.openstack, 'volume snapshot delete ' + new_name)
#[YS] 값 확인
self.assertEqual(
name,
cmd_output["name"],
)
self.assertEqual(
1,
cmd_output["size"],
)
self.assertEqual(
'aaaa',
cmd_output["description"],
)
self.assertEqual(
{'Alpha': 'a'},
cmd_output["properties"],
)
self.wait_for_status('volume snapshot', name, 'available')
# Test volume snapshot set
raw_output = self.openstack(
'volume snapshot set '
+ '--name '
+ new_name
+ ' --description bbbb '
+ '--property Alpha=c '
+ '--property Beta=b '
+ name,
)
self.assertOutput('', raw_output)
# Show snapshot set result
cmd_output = self.openstack(
'volume snapshot show ' + new_name,
parse_output=True,
)
self.assertEqual(
new_name,
cmd_output["name"],
)
self.assertEqual(
1,
cmd_output["size"],
)
self.assertEqual(
'bbbb',
cmd_output["description"],
)
self.assertEqual(
{'Alpha': 'c', 'Beta': 'b'},
cmd_output["properties"],
)
# Test volume snapshot unset
raw_output = self.openstack(
'volume snapshot unset ' + '--property Alpha ' + new_name,
)
self.assertOutput('', raw_output)
cmd_output = self.openstack(
'volume snapshot show ' + new_name,
parse_output=True,
)
self.assertEqual(
{'Beta': 'b'},
cmd_output["properties"],
)
# Test volume snapshot set --no-property
raw_output = self.openstack(
'volume snapshot set ' + '--no-property ' + new_name,
)
self.assertOutput('', raw_output)
cmd_output = self.openstack(
'volume snapshot show ' + new_name,
parse_output=True,
)
self.assertNotIn(
{'Beta': 'b'},
cmd_output["properties"],
)
Target output
-
openstack volume snapshot show $snapshot-name
Fields 확인 필요 -
openstack volume snapshot unset $change_value
change value 변경 필요
Type functional test code
- openstack volume snapshot show $snapshot-name
def test_volume_snapshot_show(self):
"""Test showing a volume snapshot"""
# 1. UUID 기반 이름 생성
name1 = uuid.uuid4().hex
# 2. Snapshot 생성
cmd_output = self.openstack(
'volume snapshot create'
+ ' --volume '
+ self.VOLLY
+ ' --description "test snapshot"'
+ ' --property test_key=test_value '
+ name1,
parse_output=True,
)
# 3. 삭제 예약
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
# 4. 상태 대기
self.wait_for_status('volume snapshot', name1, 'available')
# 5.show 부르기
snapshot_info = self.openstack(
'volume snapshot show ' + name1,
parse_output=True,
)
print(snapshot_info)
# 6. 값 확인하기
self.assertEqual(name1, snapshot_info['name'])
self.assertEqual(cmd_output['id'], snapshot_info['id'])
self.assertEqual(cmd_output['created_at'], snapshot_info['created_at'])
self.assertEqual(self.VOLUME_ID, snapshot_info["volume_id"])
self.assertEqual("test snapshot", snapshot_info["description"])
self.assertEqual(
{"test_key": "test_value"}, snapshot_info["properties"]
)
self.assertEqual(1, snapshot_info["size"])
self.assertEqual("available", snapshot_info["status"])
위와 같이 microsecond 단위로 인해 문제가 발생하므로 수정해줬습니다.
self.assertEqual(cmd_output['created_at'][:16] , snapshot_info['created_at'][:16])
microsecond 단위를 제외하고 비교하도록 파싱했습니다. 실시간성이 중요한 게 아니니 괜찮겠죠? >> 이건 질문하도록 하겠습니다
- openstack volume snapshot unset $change_value
def test_volume_snapshot_unset(self):
"""Test unsetting properies of a volume snapshot"""
name = uuid.uuid4().hex
cmd_output = self.openstack(
'volume snapshot create'
+ ' --volume '
+ self.VOLLY
+ ' --property Alpha=a '
+ name,
parse_output=True,
)
self.addCleanup(self.wait_for_delete, 'volume snapshot', name)
self.addCleanup(self.openstack, 'volume snapshot delete ' + name)
self.wait_for_status('volume snapshot', name, 'available')
raw_output = self.openstack(
'volume snapshot unset ' + '--property Alpha ' + name,
)
self.assertOutput('', raw_output)
cmd_output = self.openstack(
'volume snapshot show ' + name,
parse_output=True,
)
self.assertEqual({}, cmd_output["properties"])
Test result
tox -e functional -- openstackclient.tests.functional.volume.v3.test_volume_snapshot.VolumeSnapshotTests



