Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
tp-qemu
提交
ad441941
T
tp-qemu
项目概览
openeuler
/
tp-qemu
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
tp-qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ad441941
编写于
4月 01, 2018
作者:
X
Xu Han
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[qemu] Replace autotest modules - #ab
Signed-off-by:
N
Xu Han
<
xuhan@redhat.com
>
上级
d9bf87b9
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
176 addition
and
177 deletion
+176
-177
qemu/tests/9p.py
qemu/tests/9p.py
+1
-3
qemu/tests/audio.py
qemu/tests/audio.py
+4
-4
qemu/tests/balloon_disable.py
qemu/tests/balloon_disable.py
+1
-4
qemu/tests/balloon_stop_continue.py
qemu/tests/balloon_stop_continue.py
+6
-5
qemu/tests/blk_stream.py
qemu/tests/blk_stream.py
+7
-8
qemu/tests/block_copy.py
qemu/tests/block_copy.py
+32
-32
qemu/tests/block_discard.py
qemu/tests/block_discard.py
+22
-18
qemu/tests/block_resize.py
qemu/tests/block_resize.py
+23
-26
qemu/tests/block_stream_drop_backingfile.py
qemu/tests/block_stream_drop_backingfile.py
+26
-25
qemu/tests/block_stream_negative.py
qemu/tests/block_stream_negative.py
+9
-8
qemu/tests/block_stream_simple.py
qemu/tests/block_stream_simple.py
+6
-4
qemu/tests/boot_cpu_model.py
qemu/tests/boot_cpu_model.py
+5
-8
qemu/tests/boot_from_device.py
qemu/tests/boot_from_device.py
+5
-5
qemu/tests/boot_order_check.py
qemu/tests/boot_order_check.py
+3
-2
qemu/tests/boot_time.py
qemu/tests/boot_time.py
+8
-9
qemu/tests/boot_with_different_vectors.py
qemu/tests/boot_with_different_vectors.py
+18
-16
未找到文件。
qemu/tests/9p.py
浏览文件 @
ad441941
import
os
import
logging
from
autotest.client.shared
import
error
from
virttest
import
utils_test
...
...
@@ -45,7 +43,7 @@ def run(test, params, env):
if
(
mount_status
!=
0
):
logging
.
error
(
"mount failed"
)
raise
error
.
TestF
ail
(
'mount failed.'
)
test
.
f
ail
(
'mount failed.'
)
# Collect test parameters
timeout
=
int
(
params
.
get
(
"test_timeout"
,
14400
))
...
...
qemu/tests/audio.py
浏览文件 @
ad441941
from
autotest.client.shared
import
error
from
virttest
import
error_context
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
Test guest audio:
...
...
@@ -19,8 +19,8 @@ def run(test, params, env):
random_content_size
=
params
.
get
(
"random_content_size"
)
audio_device
=
params
.
get
(
"audio_device"
)
error
.
context
(
"Verifying whether /dev/dsp is present"
)
error
_context
.
context
(
"Verifying whether /dev/dsp is present"
)
session
.
cmd
(
"test -c %s"
%
audio_device
)
error
.
context
(
"Trying to write to the device"
)
error
_context
.
context
(
"Trying to write to the device"
)
session
.
cmd
(
"dd if=/dev/urandom of=%s bs=%s count=1"
%
(
audio_device
,
random_content_size
))
qemu/tests/balloon_disable.py
浏览文件 @
ad441941
from
autotest.client.shared
import
error
from
virttest
import
qemu_monitor
...
...
@@ -23,6 +21,5 @@ def run(test, params, env):
output
=
str
(
e
)
if
not
(
"has not been activated"
in
output
or
"No balloon device has been activated"
in
output
):
raise
error
.
TestFail
(
"Balloon driver still on when disable"
" it on command line"
)
test
.
fail
(
"Balloon driver still on when disable it on command line"
)
session
.
close
()
qemu/tests/balloon_stop_continue.py
浏览文件 @
ad441941
import
time
import
logging
import
random
from
autotest.client.shared
import
error
from
virttest
import
error_context
@
error
.
context_aware
@
error_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
Query balloon memory size, stop and continue vm from monitor
...
...
@@ -24,14 +25,14 @@ def run(test, params, env):
timeout
=
int
(
params
.
get
(
"login_timeout"
,
360
))
end_time
=
time
.
time
()
+
repeat_timeout
while
time
.
time
()
<
end_time
:
error
.
context
(
"Query balloon memory from monitor"
,
logging
.
info
)
error
_context
.
context
(
"Query balloon memory from monitor"
,
logging
.
info
)
vm
.
monitor
.
info
(
"balloon"
)
error
.
context
(
"Stop and continue vm from monitor"
,
logging
.
info
)
error
_context
.
context
(
"Stop and continue vm from monitor"
,
logging
.
info
)
vm
.
monitor
.
cmd
(
"stop"
)
vm
.
monitor
.
cmd
(
'cont'
)
vm
.
verify_alive
()
time
.
sleep
(
random
.
randint
(
0
,
3
))
error
.
context
(
"Login guest after the test"
,
logging
.
info
)
error
_context
.
context
(
"Login guest after the test"
,
logging
.
info
)
session
=
vm
.
wait_for_login
(
timeout
=
timeout
)
session
.
close
()
qemu/tests/blk_stream.py
浏览文件 @
ad441941
import
logging
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
virttest
import
utils_misc
from
qemu.tests
import
block_copy
...
...
@@ -25,7 +24,7 @@ class BlockStream(block_copy.BlockCopy):
self
.
default_params
.
update
(
default_params
)
return
super
(
BlockStream
,
self
).
parser_test_args
()
@
error
.
context_aware
@
error
_context
.
context_aware
def
start
(
self
):
"""
start block device streaming job;
...
...
@@ -33,16 +32,16 @@ class BlockStream(block_copy.BlockCopy):
params
=
self
.
parser_test_args
()
default_speed
=
params
.
get
(
"default_speed"
)
error
.
context
(
"start to stream block device"
,
logging
.
info
)
error
_context
.
context
(
"start to stream block device"
,
logging
.
info
)
self
.
vm
.
block_stream
(
self
.
device
,
default_speed
,
self
.
base_image
,
self
.
ext_args
)
status
=
self
.
get_status
()
if
not
status
:
raise
error
.
TestF
ail
(
"no active job found"
)
self
.
test
.
f
ail
(
"no active job found"
)
msg
=
"block stream job running, "
msg
+=
"with limited speed %s B/s"
%
default_speed
logging
.
info
(
msg
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
create_snapshots
(
self
):
"""
create live snapshot_chain, snapshots chain define in $snapshot_chain
...
...
@@ -50,7 +49,7 @@ class BlockStream(block_copy.BlockCopy):
params
=
self
.
parser_test_args
()
image_format
=
params
[
"snapshot_format"
]
snapshots
=
params
[
"snapshot_chain"
].
split
()
error
.
context
(
"create live snapshots"
,
logging
.
info
)
error
_context
.
context
(
"create live snapshots"
,
logging
.
info
)
for
snapshot
in
snapshots
:
snapshot
=
utils_misc
.
get_path
(
self
.
data_dir
,
snapshot
)
image_file
=
self
.
get_image_file
()
...
...
@@ -59,7 +58,7 @@ class BlockStream(block_copy.BlockCopy):
image_file
=
self
.
get_image_file
()
logging
.
info
(
"expect file: %s"
%
snapshot
+
"opening file: %s"
%
image_file
)
raise
error
.
TestF
ail
(
"create snapshot '%s' fail"
%
snapshot
)
self
.
test
.
f
ail
(
"create snapshot '%s' fail"
%
snapshot
)
self
.
trash_files
.
append
(
snapshot
)
def
action_when_streaming
(
self
):
...
...
qemu/tests/block_copy.py
浏览文件 @
ad441941
...
...
@@ -3,10 +3,10 @@ import time
import
random
import
logging
from
autotest.client.shared
import
utils
from
autotest.client.shared
import
error
from
avocado.utils
import
process
from
virttest
import
data_dir
from
virttest
import
error_context
from
virttest
import
storage
from
virttest
import
qemu_storage
from
virttest
import
utils_misc
...
...
@@ -113,11 +113,11 @@ class BlockCopy(object):
fun
=
getattr
(
self
,
step
)
fun
()
else
:
error
.
TestE
rror
(
"undefined step %s"
%
step
)
self
.
test
.
e
rror
(
"undefined step %s"
%
step
)
except
KeyError
:
logging
.
warn
(
"Undefined test phase '%s'"
%
tag
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
cancel
(
self
):
"""
cancel active job on given image;
...
...
@@ -127,7 +127,7 @@ class BlockCopy(object):
ret
&=
bool
(
self
.
vm
.
monitor
.
get_event
(
"BLOCK_JOB_CANCELLED"
))
return
ret
error
.
context
(
"cancel block copy job"
,
logging
.
info
)
error
_context
.
context
(
"cancel block copy job"
,
logging
.
info
)
params
=
self
.
parser_test_args
()
timeout
=
params
.
get
(
"cancel_timeout"
)
self
.
vm
.
monitor
.
clear_event
(
"BLOCK_JOB_CANCELLED"
)
...
...
@@ -135,7 +135,7 @@ class BlockCopy(object):
cancelled
=
utils_misc
.
wait_for
(
is_cancelled
,
timeout
=
timeout
)
if
not
cancelled
:
msg
=
"Cancel block job timeout in %ss"
%
timeout
raise
error
.
TestF
ail
(
msg
)
self
.
test
.
f
ail
(
msg
)
self
.
vm
.
monitor
.
clear_event
(
"BLOCK_JOB_CANCELLED"
)
def
is_paused
(
self
):
...
...
@@ -163,25 +163,25 @@ class BlockCopy(object):
pause active job;
"""
if
self
.
is_paused
():
raise
error
.
TestE
rror
(
"Job has been already paused."
)
self
.
test
.
e
rror
(
"Job has been already paused."
)
logging
.
info
(
"Pause block job."
)
self
.
vm
.
pause_block_job
(
self
.
device
)
time
.
sleep
(
5
)
if
not
self
.
is_paused
():
raise
error
.
TestF
ail
(
"Pause block job failed."
)
self
.
test
.
f
ail
(
"Pause block job failed."
)
def
resume_job
(
self
):
"""
resume a paused job.
"""
if
not
self
.
is_paused
():
raise
error
.
TestE
rror
(
"Job is not paused, can't be resume."
)
self
.
test
.
e
rror
(
"Job is not paused, can't be resume."
)
logging
.
info
(
"Resume block job."
)
self
.
vm
.
resume_block_job
(
self
.
device
)
if
self
.
is_paused
():
raise
error
.
TestF
ail
(
"Resume block job failed."
)
self
.
test
.
f
ail
(
"Resume block job failed."
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
set_speed
(
self
):
"""
set limited speed for block job;
...
...
@@ -189,23 +189,24 @@ class BlockCopy(object):
params
=
self
.
parser_test_args
()
max_speed
=
params
.
get
(
"max_speed"
)
expected_speed
=
int
(
params
.
get
(
"expected_speed"
,
max_speed
))
error
.
context
(
"set speed to %s B/s"
%
expected_speed
,
logging
.
info
)
error_context
.
context
(
"set speed to %s B/s"
%
expected_speed
,
logging
.
info
)
self
.
vm
.
set_job_speed
(
self
.
device
,
expected_speed
)
status
=
self
.
get_status
()
if
not
status
:
raise
error
.
TestF
ail
(
"Unable to query job status."
)
self
.
test
.
f
ail
(
"Unable to query job status."
)
speed
=
status
[
"speed"
]
if
speed
!=
expected_speed
:
msg
=
"Set speed fail. (expected speed: %s B/s,"
%
expected_speed
msg
+=
"actual speed: %s B/s)"
%
speed
raise
error
.
TestF
ail
(
msg
)
self
.
test
.
f
ail
(
msg
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
reboot
(
self
,
method
=
"shell"
,
boot_check
=
True
):
"""
reboot VM, alias of vm.reboot();
"""
error
.
context
(
"reboot vm"
,
logging
.
info
)
error
_context
.
context
(
"reboot vm"
,
logging
.
info
)
params
=
self
.
parser_test_args
()
timeout
=
params
[
"login_timeout"
]
...
...
@@ -213,42 +214,42 @@ class BlockCopy(object):
session
=
self
.
get_session
()
return
self
.
vm
.
reboot
(
session
=
session
,
timeout
=
timeout
,
method
=
method
)
error
.
context
(
"reset guest via system_reset"
,
logging
.
info
)
error
_context
.
context
(
"reset guest via system_reset"
,
logging
.
info
)
self
.
vm
.
monitor
.
clear_event
(
"RESET"
)
self
.
vm
.
monitor
.
cmd
(
"system_reset"
)
reseted
=
utils_misc
.
wait_for
(
lambda
:
self
.
vm
.
monitor
.
get_event
(
"RESET"
),
timeout
=
timeout
)
if
not
reseted
:
raise
error
.
TestF
ail
(
"No RESET event received after"
"execute system_reset %ss"
%
timeout
)
self
.
test
.
f
ail
(
"No RESET event received after"
"execute system_reset %ss"
%
timeout
)
self
.
vm
.
monitor
.
clear_event
(
"RESET"
)
return
None
@
error
.
context_aware
@
error
_context
.
context_aware
def
stop
(
self
):
"""
stop vm and verify it is really paused;
"""
error
.
context
(
"stop vm"
,
logging
.
info
)
error
_context
.
context
(
"stop vm"
,
logging
.
info
)
self
.
vm
.
pause
()
return
self
.
vm
.
verify_status
(
"paused"
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
resume
(
self
):
"""
resume vm and verify it is really running;
"""
error
.
context
(
"resume vm"
,
logging
.
info
)
error
_context
.
context
(
"resume vm"
,
logging
.
info
)
self
.
vm
.
resume
()
return
self
.
vm
.
verify_status
(
"running"
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
verify_alive
(
self
):
"""
check guest can response command correctly;
"""
error
.
context
(
"verify guest alive"
,
logging
.
info
)
error
_context
.
context
(
"verify guest alive"
,
logging
.
info
)
params
=
self
.
parser_test_args
()
session
=
self
.
get_session
()
cmd
=
params
.
get
(
"alive_check_cmd"
,
"dir"
)
...
...
@@ -314,7 +315,7 @@ class BlockCopy(object):
for
test
in
self
.
params
.
get
(
"when_start"
).
split
():
if
hasattr
(
self
,
test
):
fun
=
getattr
(
self
,
test
)
bg
=
utils
.
InterruptedThread
(
fun
)
bg
=
utils
_misc
.
InterruptedThread
(
fun
)
bg
.
start
()
if
bg
.
isAlive
():
self
.
processes
.
append
(
bg
)
...
...
@@ -336,7 +337,7 @@ class BlockCopy(object):
timeout
=
params
.
get
(
"wait_timeout"
)
finished
=
utils_misc
.
wait_for
(
self
.
job_finished
,
timeout
=
timeout
)
if
not
finished
:
raise
error
.
TestF
ail
(
"Job not finished in %s seconds"
%
timeout
)
self
.
test
.
f
ail
(
"Job not finished in %s seconds"
%
timeout
)
time_end
=
time
.
time
()
logging
.
info
(
"Block job done."
)
return
time_end
-
time_start
...
...
@@ -373,8 +374,7 @@ class BlockCopy(object):
steady
=
utils_misc
.
wait_for
(
self
.
is_steady
,
first
=
3.0
,
step
=
3.0
,
timeout
=
timeout
)
if
not
steady
:
raise
error
.
TestFail
(
"Wait mirroring job ready "
"timeout in %ss"
%
timeout
)
self
.
test
.
fail
(
"Wait mirroring job ready timeout in %ss"
%
timeout
)
def
action_before_steady
(
self
):
"""
...
...
@@ -409,7 +409,7 @@ class BlockCopy(object):
self
.
vm
.
destroy
()
while
self
.
trash_files
:
tmp_file
=
self
.
trash_files
.
pop
()
util
s
.
system
(
"rm -f %s"
%
tmp_file
,
ignore_status
=
True
)
proces
s
.
system
(
"rm -f %s"
%
tmp_file
,
ignore_status
=
True
)
def
create_file
(
self
,
file_name
):
"""
...
...
@@ -438,8 +438,8 @@ class BlockCopy(object):
status
,
output
=
session
.
cmd_status_output
(
"md5sum -c %s.md5"
%
file_name
,
timeout
=
200
)
if
status
!=
0
:
raise
error
.
TestFail
(
"File %s changed, md5sum check output: %s"
%
(
file_name
,
output
))
self
.
test
.
fail
(
"File %s changed, md5sum check output: %s"
%
(
file_name
,
output
))
def
reopen
(
self
,
reopen_image
):
"""
...
...
qemu/tests/block_discard.py
浏览文件 @
ad441941
...
...
@@ -2,14 +2,15 @@ import os
import
re
import
logging
from
a
utotest.client
import
os_dep
from
a
utotest.client.shared
import
error
from
a
utotest.client.shared
import
util
s
from
a
vocado.utils
import
genio
from
a
vocado.utils
import
path
as
utils_path
from
a
vocado.utils
import
proces
s
from
virttest
import
env_process
from
virttest
import
error_context
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
Qemu discard support test:
...
...
@@ -31,7 +32,7 @@ def run(test, params, env):
"""
Get latest scsi disk which emulated by scsi_debug module.
"""
scsi_disk_info
=
util
s
.
system_output
(
"lsscsi"
).
splitlines
()
scsi_disk_info
=
proces
s
.
system_output
(
"lsscsi"
).
splitlines
()
scsi_debug
=
[
_
for
_
in
scsi_disk_info
if
'scsi_debug'
in
_
][
-
1
]
scsi_debug
=
scsi_debug
.
split
()
host_id
=
scsi_debug
[
0
][
1
:
-
1
]
...
...
@@ -54,7 +55,7 @@ def run(test, params, env):
device_name
=
os
.
path
.
basename
(
device
)
path
=
"/sys/block/%s/device/scsi_disk"
%
device_name
path
+=
"/%s/provisioning_mode"
%
host_id
return
utils
.
read_one_line
(
path
).
strip
()
return
genio
.
read_one_line
(
path
).
strip
()
def
get_allocation_bitmap
():
"""
...
...
@@ -62,7 +63,7 @@ def run(test, params, env):
"""
path
=
"/sys/bus/pseudo/drivers/scsi_debug/map"
try
:
return
utils
.
read_one_line
(
path
).
strip
()
return
genio
.
read_one_line
(
path
).
strip
()
except
IOError
:
logging
.
warn
(
"block allocation bitmap not exists"
)
return
""
...
...
@@ -73,14 +74,14 @@ def run(test, params, env):
vm
.
destroy
()
env
.
unregister_vm
(
vm
.
name
)
os_dep
.
command
(
"lsscsi"
)
utils_path
.
find_
command
(
"lsscsi"
)
host_id
,
disk_name
=
get_host_scsi_disk
()
provisioning_mode
=
get_provisioning_mode
(
disk_name
,
host_id
)
logging
.
info
(
"Current provisioning_mode = '%s'"
,
provisioning_mode
)
bitmap
=
get_allocation_bitmap
()
if
bitmap
:
logging
.
debug
(
"block allocation bitmap: %s"
%
bitmap
)
raise
error
.
TestE
rror
(
"block allocation bitmap not empty before test."
)
test
.
e
rror
(
"block allocation bitmap not empty before test."
)
# prepare params to boot vm with scsi_debug disk.
vm_name
=
params
[
"main_vm"
]
...
...
@@ -92,7 +93,8 @@ def run(test, params, env):
params
[
"force_create_image_%s"
%
test_image
]
=
"no"
params
[
"images"
]
=
" "
.
join
([
params
[
"images"
],
test_image
])
error
.
context
(
"boot guest with disk '%s'"
%
disk_name
,
logging
.
info
)
error_context
.
context
(
"boot guest with disk '%s'"
%
disk_name
,
logging
.
info
)
# boot guest with scsi_debug disk
env_process
.
preprocess_vm
(
test
,
params
,
env
,
vm_name
)
vm
=
env
.
get_vm
(
vm_name
)
...
...
@@ -100,7 +102,8 @@ def run(test, params, env):
timeout
=
float
(
params
.
get
(
"login_timeout"
,
240
))
session
=
vm
.
wait_for_login
(
timeout
=
timeout
)
error
.
context
(
"Fresh block allocation bitmap before test."
,
logging
.
info
)
error_context
.
context
(
"Fresh block allocation bitmap before test."
,
logging
.
info
)
device_name
=
get_guest_discard_disk
(
session
)
rewrite_disk_cmd
=
params
[
"rewrite_disk_cmd"
]
rewrite_disk_cmd
=
rewrite_disk_cmd
.
replace
(
"DISK"
,
device_name
)
...
...
@@ -109,27 +112,28 @@ def run(test, params, env):
bitmap_before_trim
=
get_allocation_bitmap
()
if
not
re
.
match
(
r
"\d+-\d+"
,
bitmap_before_trim
):
logging
.
debug
(
"bitmap before test: %s"
%
bitmap_before_trim
)
raise
error
.
TestF
ail
(
"bitmap should be continuous before fstrim"
)
test
.
f
ail
(
"bitmap should be continuous before fstrim"
)
format_disk_cmd
=
params
[
"format_disk_cmd"
]
format_disk_cmd
=
format_disk_cmd
.
replace
(
"DISK"
,
device_name
)
error
.
context
(
"format disk '%s' in guest"
%
device_name
,
logging
.
info
)
error_context
.
context
(
"format disk '%s' in guest"
%
device_name
,
logging
.
info
)
session
.
cmd
(
format_disk_cmd
)
error
.
context
(
"mount disk with discard options '%s'"
%
device_name
,
logging
.
info
)
error
_context
.
context
(
"mount disk with discard options '%s'"
%
device_name
,
logging
.
info
)
mount_disk_cmd
=
params
[
"mount_disk_cmd"
]
mount_disk_cmd
=
mount_disk_cmd
.
replace
(
"DISK"
,
device_name
)
session
.
cmd
(
mount_disk_cmd
)
error
.
context
(
"execute fstrim in guest"
,
logging
.
info
)
error
_context
.
context
(
"execute fstrim in guest"
,
logging
.
info
)
fstrim_cmd
=
params
[
"fstrim_cmd"
]
session
.
cmd
(
fstrim_cmd
,
timeout
=
timeout
)
bitmap_after_trim
=
get_allocation_bitmap
()
if
not
re
.
match
(
r
"\d+-\d+,.*\d+-\d+$"
,
bitmap_after_trim
):
logging
.
debug
(
"bitmap after test: %s"
%
bitmap_before_trim
)
raise
error
.
TestF
ail
(
"discard command doesn't issue"
"to scsi_debug disk, please report bug for qemu"
)
test
.
f
ail
(
"discard command doesn't issue"
"to scsi_debug disk, please report bug for qemu"
)
if
vm
:
vm
.
destroy
()
qemu/tests/block_resize.py
浏览文件 @
ad441941
import
logging
import
re
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
virttest
import
utils_misc
from
virttest
import
utils_test
from
virttest
import
storage
from
virttest
import
data_dir
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
KVM block resize test:
...
...
@@ -34,9 +33,9 @@ def run(test, params, env):
return
float
(
utils_misc
.
normalize_data_size
(
block_size
[
0
],
order_magnitude
=
"B"
))
else
:
raise
error
.
TestE
rror
(
"Can not find the block size for the"
" deivce. The output of command"
" is: %s"
%
output
)
test
.
e
rror
(
"Can not find the block size for the"
" deivce. The output of command"
" is: %s"
%
output
)
def
compare_block_size
(
session
,
block_cmd
,
block_pattern
):
"""
...
...
@@ -83,28 +82,27 @@ def run(test, params, env):
test
.
fail
(
"No available tag to get drive id"
)
drive_path
=
utils_misc
.
get_linux_drive_path
(
session
,
drive_id
)
if
not
drive_path
:
raise
error
.
TestError
(
"Failed to get '%s' drive path"
%
data_image
)
test
.
error
(
"Failed to get '%s' drive path"
%
data_image
)
block_size_cmd
=
params
[
"block_size_cmd"
].
format
(
drive_path
)
block_size_pattern
=
params
.
get
(
"block_size_pattern"
)
need_reboot
=
params
.
get
(
"need_reboot"
,
"no"
)
==
"yes"
accept_ratio
=
float
(
params
.
get
(
"accept_ratio"
,
0
))
error
.
context
(
"Check image size in guest"
,
logging
.
info
)
error
_context
.
context
(
"Check image size in guest"
,
logging
.
info
)
block_size
=
get_block_size
(
session
,
block_size_cmd
,
block_size_pattern
)
if
(
block_size
>
data_image_size
or
block_size
<
data_image_size
*
(
1
-
accept_ratio
)):
raise
error
.
TestE
rror
(
"Image size from guest and image not match"
"Block size get from guest: %s
\n
"
"Image size get from image: %s
\n
"
%
(
block_size
,
data_image_size
))
test
.
e
rror
(
"Image size from guest and image not match"
"Block size get from guest: %s
\n
"
"Image size get from image: %s
\n
"
%
(
block_size
,
data_image_size
))
if
params
.
get
(
"guest_prepare_cmd"
):
session
.
cmd
(
params
.
get
(
"guest_prepare_cmd"
))
if
params
.
get
(
"format_disk"
,
"no"
)
==
"yes"
:
error
.
context
(
"Format disk"
,
logging
.
info
)
error
_context
.
context
(
"Format disk"
,
logging
.
info
)
utils_misc
.
format_windows_disk
(
session
,
params
[
"disk_index"
],
mountpoint
=
params
[
"disk_letter"
])
...
...
@@ -141,24 +139,24 @@ def run(test, params, env):
# We need shrink the disk in guest first, than in monitor
if
block_size
<
old_block_size
and
disk_update_cmd
:
error
.
context
(
"Shrink disk size to %s in guest"
%
block_size
,
logging
.
info
)
error
_context
.
context
(
"Shrink disk size to %s in guest"
%
block_size
,
logging
.
info
)
session
.
cmd
(
disk_update_cmd
[
index
])
error
.
context
(
"Change disk size to %s in monitor"
%
block_size
,
logging
.
info
)
error
_context
.
context
(
"Change disk size to %s in monitor"
%
block_size
,
logging
.
info
)
vm
.
monitor
.
block_resize
(
data_image_dev
,
block_size
)
if
need_reboot
:
session
=
vm
.
reboot
(
session
=
session
)
elif
disk_rescan_cmd
:
error
.
context
(
"Rescan disk"
,
logging
.
info
)
error
_context
.
context
(
"Rescan disk"
,
logging
.
info
)
session
.
cmd
(
disk_rescan_cmd
)
# We need expand disk in monitor first than extend it in guest
if
block_size
>
old_block_size
and
disk_update_cmd
:
error
.
context
(
"Extend disk to %s in guest"
%
block_size
,
logging
.
info
)
error
_context
.
context
(
"Extend disk to %s in guest"
%
block_size
,
logging
.
info
)
session
.
cmd
(
disk_update_cmd
[
index
])
global
current_size
...
...
@@ -167,8 +165,7 @@ def run(test, params, env):
(
session
,
block_size_cmd
,
block_size_pattern
),
20
,
0
,
1
,
"Block Resizing"
):
raise
error
.
TestFail
(
"Block size get from guest is not"
"the same as expected
\n
"
"Reported: %s
\n
"
"Expect: %s
\n
"
%
(
current_size
,
block_size
))
test
.
fail
(
"Block size get from guest is not"
"the same as expected
\n
"
"Reported: %s
\n
"
"Expect: %s
\n
"
%
(
current_size
,
block_size
))
qemu/tests/block_stream_drop_backingfile.py
浏览文件 @
ad441941
...
...
@@ -2,15 +2,15 @@ import os
import
re
import
logging
from
autotest.client
import
utils
from
autotest.client.shared
import
error
from
avocado.utils
import
process
from
virttest
import
error_context
from
virttest
import
storage
from
virttest
import
utils_misc
from
virttest
import
data_dir
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
block_stream_without_backingfile test:
...
...
@@ -46,7 +46,7 @@ def run(test, params, env):
not
vm
.
monitor
.
query_block_job
(
device_id
),
timeout
,
first
=
0.2
,
step
=
2.0
,
text
=
"Wait for canceling block job"
)
is
None
:
raise
error
.
TestF
ail
(
"Wait job finish timeout in %ss"
%
timeout
)
test
.
f
ail
(
"Wait job finish timeout in %ss"
%
timeout
)
def
verify_backingfile
(
expect_backingfile
):
"""
...
...
@@ -55,7 +55,7 @@ def run(test, params, env):
"""
backing_file
=
vm
.
monitor
.
get_backingfile
(
device_id
)
if
backing_file
!=
expect_backingfile
:
raise
error
.
TestF
ail
(
"Unexpect backingfile(%s)"
%
backing_file
)
test
.
f
ail
(
"Unexpect backingfile(%s)"
%
backing_file
)
def
get_openingfiles
():
"""
...
...
@@ -63,47 +63,48 @@ def run(test, params, env):
"""
pid
=
vm
.
get_pid
()
cmd
=
params
.
get
(
"snapshot_check_cmd"
)
%
pid
return
set
(
util
s
.
system_output
(
cmd
,
ignore_status
=
True
).
splitlines
())
return
set
(
proces
s
.
system_output
(
cmd
,
ignore_status
=
True
).
splitlines
())
snapshots
=
map
(
lambda
x
:
os
.
path
.
join
(
image_dir
,
x
),
[
"sn1"
,
"sn2"
])
try
:
error
.
context
(
"Create snapshots-chain(base->sn1->sn2)"
,
logging
.
info
)
error_context
.
context
(
"Create snapshots-chain(base->sn1->sn2)"
,
logging
.
info
)
for
index
,
snapshot
in
enumerate
(
snapshots
):
base_file
=
index
and
snapshots
[
index
-
1
]
or
image_file
device_id
=
vm
.
live_snapshot
(
base_file
,
snapshot
)
if
not
device_id
:
raise
error
.
TestF
ail
(
"Fail to create %s"
%
snapshot
)
error
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
test
.
f
ail
(
"Fail to create %s"
%
snapshot
)
error
_context
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
verify_backingfile
(
snapshots
[
0
])
error
.
context
(
"Merge sn1 to sn2"
,
logging
.
info
)
error
_context
.
context
(
"Merge sn1 to sn2"
,
logging
.
info
)
vm
.
monitor
.
block_stream
(
device_id
,
base
=
image_file
,
speed
=
speed
)
wait_job_done
(
wait_timeout
)
error
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
error
_context
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
verify_backingfile
(
image_file
)
error
.
context
(
"Check sn1 is not opening by qemu process"
,
logging
.
info
)
error
_context
.
context
(
"Check sn1 is not opening by qemu process"
,
logging
.
info
)
if
snapshots
[
0
]
in
get_openingfiles
():
raise
error
.
TestF
ail
(
"sn1 (%s) is opening by qemu"
%
snapshots
[
0
])
test
.
f
ail
(
"sn1 (%s) is opening by qemu"
%
snapshots
[
0
])
error
.
context
(
"Merge base to sn2"
,
logging
.
info
)
error
_context
.
context
(
"Merge base to sn2"
,
logging
.
info
)
vm
.
monitor
.
block_stream
(
device_id
)
wait_job_done
(
wait_timeout
)
error
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
error
_context
.
context
(
"Check backing-file of sn2"
,
logging
.
info
)
verify_backingfile
(
None
)
error
.
context
(
"check sn1 and base are not opening by qemu process"
,
logging
.
info
)
error
_context
.
context
(
"check sn1 and base are not opening "
"by qemu process"
,
logging
.
info
)
if
set
([
snapshots
[
0
],
image_file
]).
issubset
(
get_openingfiles
()):
raise
error
.
TestFail
(
"%s is opening by qemu"
%
set
([
snapshots
[
0
],
image_file
]))
error
.
context
(
"Check backing-file of sn2 by qemu-img"
,
logging
.
info
)
test
.
fail
(
"%s is opening by qemu"
%
set
([
snapshots
[
0
],
image_file
]))
error
_context
.
context
(
"Check backing-file of sn2 by qemu-img"
,
logging
.
info
)
cmd
=
"%s info %s"
%
(
qemu_img
,
snapshots
[
1
])
if
re
.
search
(
"backing file"
,
util
s
.
system_output
(
cmd
,
ignore_status
=
True
)):
raise
error
.
TestF
ail
(
"should no backing-file in this step"
)
proces
s
.
system_output
(
cmd
,
ignore_status
=
True
)):
test
.
f
ail
(
"should no backing-file in this step"
)
error
.
context
(
"Reboot VM to check it works fine"
,
logging
.
info
)
error
_context
.
context
(
"Reboot VM to check it works fine"
,
logging
.
info
)
session
=
vm
.
reboot
(
session
=
session
,
timeout
=
timeout
)
session
.
cmd
(
alive_check_cmd
)
finally
:
map
(
lambda
x
:
util
s
.
system
(
"rm -rf %s"
%
x
),
snapshots
)
map
(
lambda
x
:
proces
s
.
system
(
"rm -rf %s"
%
x
),
snapshots
)
qemu/tests/block_stream_negative.py
浏览文件 @
ad441941
import
logging
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
qemu.tests
import
blk_stream
...
...
@@ -9,7 +10,7 @@ class BlockStreamNegative(blk_stream.BlockStream):
def
__init__
(
self
,
test
,
params
,
env
,
tag
):
super
(
BlockStreamNegative
,
self
).
__init__
(
test
,
params
,
env
,
tag
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
set_speed
(
self
):
"""
set limited speed for block job;
...
...
@@ -20,17 +21,17 @@ class BlockStreamNegative(blk_stream.BlockStream):
expected_speed
=
params
.
get
(
"expected_speed"
,
default_speed
)
if
params
.
get
(
"need_convert_to_int"
,
"no"
)
==
"yes"
:
expected_speed
=
int
(
expected_speed
)
error
.
context
(
"set speed to %s B/s"
%
expected_speed
,
logging
.
info
)
error_context
.
context
(
"set speed to %s B/s"
%
expected_speed
,
logging
.
info
)
args
=
{
"device"
:
self
.
device
,
"speed"
:
expected_speed
}
response
=
str
(
self
.
vm
.
monitor
.
cmd_qmp
(
"block-job-set-speed"
,
args
))
if
"(core dump)"
in
response
:
raise
error
.
TestFail
(
"Qemu core dump when reset speed
"
"
to a negative value."
)
self
.
test
.
fail
(
"Qemu core dump when reset
"
"speed
to a negative value."
)
if
match_str
not
in
response
:
raise
error
.
TestFail
(
"Fail to get expected result."
"%s is expected in %s"
%
(
match_str
,
response
))
self
.
test
.
fail
(
"Fail to get expected result. %s is expected in %s"
%
(
match_str
,
response
))
logging
.
info
(
"Keyword '%s' is found in QMP output '%s'."
%
(
match_str
,
response
))
...
...
qemu/tests/block_stream_simple.py
浏览文件 @
ad441941
import
logging
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
qemu.tests
import
blk_stream
...
...
@@ -8,14 +10,14 @@ class BlockStreamSimple(blk_stream.BlockStream):
def
__init__
(
self
,
test
,
params
,
env
,
tag
):
super
(
BlockStreamSimple
,
self
).
__init__
(
test
,
params
,
env
,
tag
)
@
error
.
context_aware
@
error
_context
.
context_aware
def
query_status
(
self
):
"""
query running block streaming job info;
"""
error
.
context
(
"query job status"
,
logging
.
info
)
error
_context
.
context
(
"query job status"
,
logging
.
info
)
if
not
self
.
get_status
():
raise
error
.
TestF
ail
(
"No active job"
)
self
.
test
.
f
ail
(
"No active job"
)
def
run
(
test
,
params
,
env
):
...
...
qemu/tests/boot_cpu_model.py
浏览文件 @
ad441941
import
logging
from
autotest.client.shared
import
error
from
virttest
import
env_process
from
virttest
import
error_context
from
virttest
import
utils_misc
from
virttest
import
utils_test
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
boot cpu model test:
...
...
@@ -25,7 +24,7 @@ def run(test, params, env):
model_list
=
params
.
get
(
"cpu_model"
)
if
not
model_list
:
if
cpu_vendor
==
"unknow"
:
raise
error
.
TestE
rror
(
"unknow cpu vendor"
)
test
.
e
rror
(
"unknow cpu vendor"
)
else
:
model_list
=
params
.
get
(
"cpu_model_%s"
%
cpu_vendor
,
host_model
[
-
1
])
...
...
@@ -53,7 +52,5 @@ def run(test, params, env):
logging
.
info
(
"shutdown guest successfully"
)
else
:
if
params
.
get
(
"enable_check"
,
"no"
)
==
"yes"
:
raise
error
.
TestWarn
(
"Can not test %s model on %s host, "
"pls use %s host"
%
(
model
,
host_model
[
0
],
model
))
test
.
cancel
(
"Can not test %s model on %s host, pls use "
"%s host"
%
(
model
,
host_model
[
0
],
model
))
qemu/tests/boot_from_device.py
浏览文件 @
ad441941
...
...
@@ -3,9 +3,9 @@ import re
import
time
import
logging
from
autotest.client
import
utils
from
virttest
import
error_context
from
avocado.utils
import
process
from
virttest
import
error_context
from
virttest
import
utils_misc
from
virttest
import
data_dir
from
virttest
import
qemu_storage
...
...
@@ -35,9 +35,9 @@ def run(test, params, env):
logging
.
info
(
"creating test cdrom"
)
cdrom_test
=
params
.
get
(
"cdrom_test"
)
cdrom_test
=
utils_misc
.
get_path
(
data_dir
.
get_data_dir
(),
cdrom_test
)
util
s
.
run
(
"dd if=/dev/urandom of=test bs=10M count=1"
)
util
s
.
run
(
"mkisofs -o %s test"
%
cdrom_test
)
util
s
.
run
(
"rm -f test"
)
proces
s
.
run
(
"dd if=/dev/urandom of=test bs=10M count=1"
)
proces
s
.
run
(
"mkisofs -o %s test"
%
cdrom_test
)
proces
s
.
run
(
"rm -f test"
)
def
cleanup_cdroms
():
"""
...
...
qemu/tests/boot_order_check.py
浏览文件 @
ad441941
...
...
@@ -2,7 +2,8 @@ import logging
import
re
import
time
from
autotest.client
import
utils
from
avocado.utils
import
process
from
virttest
import
error_context
...
...
@@ -30,7 +31,7 @@ def run(test, params, env):
# Disable nic device, boot fail from nic device except user model
if
params
[
'nettype'
]
!=
'user'
:
for
nic
in
vm
.
virtnet
:
util
s
.
system
(
"ifconfig %s down"
%
nic
.
ifname
)
proces
s
.
system
(
"ifconfig %s down"
%
nic
.
ifname
)
vm
.
resume
()
...
...
qemu/tests/boot_time.py
浏览文件 @
ad441941
import
logging
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
virttest
import
utils_misc
from
virttest
import
env_process
from
virttest.staging
import
utils_memory
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
KVM boot time test:
...
...
@@ -27,16 +26,17 @@ def run(test, params, env):
timeout
=
int
(
params
.
get
(
"login_timeout"
,
360
))
session
=
vm
.
wait_for_login
(
timeout
=
timeout
)
error
.
context
(
"Set guest run level to 1"
,
logging
.
info
)
error
_context
.
context
(
"Set guest run level to 1"
,
logging
.
info
)
single_user_cmd
=
params
[
'single_user_cmd'
]
session
.
cmd
(
single_user_cmd
)
try
:
error
.
context
(
"Shut down guest"
,
logging
.
info
)
error
_context
.
context
(
"Shut down guest"
,
logging
.
info
)
session
.
cmd
(
'sync'
)
vm
.
destroy
()
error
.
context
(
"Boot up guest and measure the boot time"
,
logging
.
info
)
error_context
.
context
(
"Boot up guest and measure the boot time"
,
logging
.
info
)
utils_memory
.
drop_caches
()
vm
.
create
()
vm
.
verify_alive
()
...
...
@@ -48,7 +48,7 @@ def run(test, params, env):
finally
:
try
:
error
.
context
(
"Restore guest run level"
,
logging
.
info
)
error
_context
.
context
(
"Restore guest run level"
,
logging
.
info
)
restore_level_cmd
=
params
[
'restore_level_cmd'
]
session
.
cmd
(
restore_level_cmd
)
session
.
cmd
(
'sync'
)
...
...
@@ -62,7 +62,6 @@ def run(test, params, env):
params
[
"restore_image_after_testing"
]
=
"yes"
if
boot_time
>
expect_time
:
raise
error
.
TestFail
(
"Guest boot up is taking too long: %ss"
%
boot_time
)
test
.
fail
(
"Guest boot up is taking too long: %ss"
%
boot_time
)
session
.
close
()
qemu/tests/boot_with_different_vectors.py
浏览文件 @
ad441941
import
logging
import
re
from
autotest.client.shared
import
error
from
virttest
import
error_context
from
virttest
import
utils_net
from
virttest
import
utils_test
from
virttest
import
env_process
from
virttest
import
virt_vm
@
error
.
context_aware
@
error
_context
.
context_aware
def
run
(
test
,
params
,
env
):
"""
Boot guest with different vectors, then do netperf testing.
...
...
@@ -27,7 +26,8 @@ def run(test, params, env):
"""
def
boot_guest_with_vectors
(
vectors
):
error
.
context
(
"Boot guest with vectors = %s"
%
vectors
,
logging
.
info
)
error_context
.
context
(
"Boot guest with vectors = %s"
%
vectors
,
logging
.
info
)
params
[
"vectors"
]
=
vectors
params
[
"start_vm"
]
=
"yes"
try
:
...
...
@@ -40,7 +40,7 @@ def run(test, params, env):
if
int
(
vectors
)
<
0
:
msg
=
"Qemu did not raise correct error"
msg
+=
" when vectors = %s"
%
vectors
raise
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
vm
=
env
.
get_vm
(
params
[
"main_vm"
])
vm
.
verify_alive
()
...
...
@@ -48,7 +48,7 @@ def run(test, params, env):
def
enable_multi_queues
(
vm
):
session
=
vm
.
wait_for_login
(
timeout
=
login_timeout
)
error
.
context
(
"Enable multi queues in guest."
,
logging
.
info
)
error
_context
.
context
(
"Enable multi queues in guest."
,
logging
.
info
)
for
nic_index
,
nic
in
enumerate
(
vm
.
virtnet
):
ifname
=
utils_net
.
get_linux_ifname
(
session
,
nic
.
mac
)
queues
=
int
(
nic
.
queues
)
...
...
@@ -57,12 +57,13 @@ def run(test, params, env):
if
status
:
msg
=
"Fail to enable multi queue in guest."
msg
+=
"Command %s, fail with output %s"
%
(
mq_set_cmd
,
output
)
error
.
TestE
rror
(
msg
)
test
.
e
rror
(
msg
)
def
check_msi_support
(
session
):
devices
=
session
.
cmd_output
(
"lspci |grep Eth"
).
strip
()
vectors
=
params
[
"vectors"
]
error
.
context
(
"Check if vnic inside guest support msi."
,
logging
.
info
)
error_context
.
context
(
"Check if vnic inside guest support msi."
,
logging
.
info
)
for
device
in
devices
.
split
(
"
\n
"
):
if
not
device
:
continue
...
...
@@ -70,7 +71,7 @@ def run(test, params, env):
msi_check_cmd
=
"lspci -vvv -s %s |grep MSI"
%
d_id
output
=
session
.
cmd_output
(
msi_check_cmd
)
if
vectors
==
0
and
output
:
error
.
TestF
ail
(
"Guest do not support msi when vectors = 0."
)
test
.
f
ail
(
"Guest do not support msi when vectors = 0."
)
if
output
:
if
vectors
==
1
:
if
"MSI-X: Enable-"
in
output
:
...
...
@@ -78,17 +79,18 @@ def run(test, params, env):
else
:
msg
=
"Command %s get wrong output."
%
msi_check_cmd
msg
+=
" when vectors = 1"
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
else
:
if
"MSI-X: Enable+"
in
output
:
logging
.
info
(
"MSI-X is enabled"
)
else
:
msg
=
"Command %s get wrong output."
%
msi_check_cmd
msg
+=
" when vectors = %s"
%
vectors
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
def
check_interrupt
(
session
,
vectors
):
error
.
context
(
"Check the cpu interrupt of virito"
,
logging
.
info
)
error_context
.
context
(
"Check the cpu interrupt of virito"
,
logging
.
info
)
cmd
=
"cat /proc/interrupts |grep virtio"
output
=
session
.
cmd_output
(
cmd
)
vectors
=
int
(
vectors
)
...
...
@@ -96,20 +98,20 @@ def run(test, params, env):
if
"IO-APIC-fasteoi"
not
in
output
:
msg
=
"Could not find IO-APIC-fasteoi interrupt"
msg
+=
" when vectors = %s"
%
vectors
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
elif
2
<=
vectors
and
vectors
<=
8
:
if
not
re
.
findall
(
"vritio[0-9]-virtqueues"
,
output
):
msg
=
"Could not find the device for msi interrupt "
msg
+=
"when vectors = %s "
%
vectors
msg
+=
"Command %s got output %s"
%
(
cmd
,
output
)
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
elif
vectors
==
9
or
vectors
==
10
:
if
not
(
re
.
findall
(
"virtio[0-9]-input"
,
output
)
and
re
.
findall
(
"virtio[0-9]-output"
,
output
)):
msg
=
"Could not find the device for msi interrupt "
msg
+=
"when vectors = %s "
%
vectors
msg
+=
"Command %s got output %s"
%
(
cmd
,
output
)
error
.
TestF
ail
(
msg
)
test
.
f
ail
(
msg
)
vectors_list
=
params
[
"vectors_list"
]
login_timeout
=
int
(
params
.
get
(
"login_timeout"
,
360
))
...
...
@@ -122,5 +124,5 @@ def run(test, params, env):
enable_multi_queues
(
vm
)
check_msi_support
(
session
)
check_interrupt
(
session
,
vectors
)
error
.
context
(
"Run netperf test in guest."
,
logging
.
info
)
error
_context
.
context
(
"Run netperf test in guest."
,
logging
.
info
)
utils_test
.
run_virt_sub_test
(
test
,
params
,
env
,
sub_type
=
sub_test
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录