Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Xts Acts
提交
fac1d5f6
X
Xts Acts
项目概览
OpenHarmony
/
Xts Acts
大约 1 年 前同步成功
通知
9
Star
22
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
Xts Acts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
fac1d5f6
编写于
5月 23, 2023
作者:
O
openharmony_ci
提交者:
Gitee
5月 23, 2023
浏览文件
操作
浏览文件
下载
差异文件
!8467 添加xts新测试子集
Merge pull request !8467 from youngshady/local_20230417_0001
上级
7b7a3d41
858726cf
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
498 addition
and
0 deletion
+498
-0
build_lite/BUILD.gn
build_lite/BUILD.gn
+5
-0
xts_lite/device_attest_lite/device_attestQuerry_posix/BUILD.gn
...ite/device_attest_lite/device_attestQuerry_posix/BUILD.gn
+34
-0
xts_lite/device_attest_lite/device_attestQuerry_posix/Test.json
...te/device_attest_lite/device_attestQuerry_posix/Test.json
+26
-0
xts_lite/device_attest_lite/device_attestQuerry_posix/src/device_attest_querry.cpp
...te/device_attestQuerry_posix/src/device_attest_querry.cpp
+139
-0
xts_lite/device_attest_lite/device_attestStart_hal/BUILD.gn
xts_lite/device_attest_lite/device_attestStart_hal/BUILD.gn
+29
-0
xts_lite/device_attest_lite/device_attestStart_hal/Test.tmpl
xts_lite/device_attest_lite/device_attestStart_hal/Test.tmpl
+19
-0
xts_lite/device_attest_lite/device_attestStart_hal/src/device_attest.c
...ce_attest_lite/device_attestStart_hal/src/device_attest.c
+138
-0
xts_lite/device_attest_lite/device_attestStart_posix/BUILD.gn
...lite/device_attest_lite/device_attestStart_posix/BUILD.gn
+34
-0
xts_lite/device_attest_lite/device_attestStart_posix/Test.json
...ite/device_attest_lite/device_attestStart_posix/Test.json
+26
-0
xts_lite/device_attest_lite/device_attestStart_posix/src/device_attest_start.cpp
...lite/device_attestStart_posix/src/device_attest_start.cpp
+48
-0
未找到文件。
build_lite/BUILD.gn
浏览文件 @
fac1d5f6
...
...
@@ -47,6 +47,7 @@ lite_component("acts_component") {
"//test/xts/acts/distributed_schedule_lite/system_ability_manager_hal:ActsSamgrTest",
"//test/xts/acts/update_lite/dupdate_hal:ActsUpdaterFuncTest",
"//test/xts/acts/startup_lite/bootstrap_hal:ActsBootstrapTest",
"//test/xts/acts/xts_lite/device_attest_lite/device_attestStart_hal:ActsDeviceAttestTest",
]
} else if (ohos_kernel_type == "uniproton") {
all_features += [
...
...
@@ -81,6 +82,8 @@ lite_component("acts_component") {
"//test/xts/acts/global_lite:ActsGlobalTest",
"//test/xts/acts/sensors_lite:sensorstest",
"//test/xts/acts/update_lite/dupdate_posix:ActsUpdateTest",
"//test/xts/acts/xts_lite/device_attest_lite/device_attestStart_posix:ActsDeviceAttestStartTest",
"//test/xts/acts/xts_lite/device_attest_lite/device_attestQuerry_posix:ActsDeviceAttestQuerryTest",
]
} else if (ohos_kernel_type == "linux") {
all_features += [
...
...
@@ -97,6 +100,8 @@ lite_component("acts_component") {
"//test/xts/acts/appexecfwk_lite/appexecfwk_posix:ActsBundleMgrTest",
"//test/xts/acts/ability_lite/ability_posix:ActsAbilityMgrTest",
"//test/xts/acts/ai_lite/ai_engine_posix/base:ActsAiEngineTest",
"//test/xts/acts/xts_lite/device_attest_lite/device_attestStart_posix:ActsDeviceAttestStartTest",
"//test/xts/acts/xts_lite/device_attest_lite/device_attestQuerry_posix:ActsDeviceAttestQuerryTest",
]
}
}
...
...
xts_lite/device_attest_lite/device_attestQuerry_posix/BUILD.gn
0 → 100644
浏览文件 @
fac1d5f6
# Copyright (c) 2023 Huawei Device Co., Ltd.
# 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("//test/xts/tools/lite/build/suite_lite.gni")
hcpptest_suite("ActsDeviceAttestQuerryTest") {
suite_name = "acts"
sources = [ "src/device_attest_querry.cpp" ]
include_dirs = [
"src",
"//test/xts/device_attest_lite/interfaces/kit/js/include",
"//test/xts/device_attest_lite/interfaces/innerkits",
"//test/xts/device_attest_lite/framework/small",
]
deps = [ "//test/xts/device_attest_lite/framework:devattest_client" ]
cflags = [ "-Wno-error" ]
ldflags = [
"-lstdc++",
"-lm",
"-lpthread",
]
}
xts_lite/device_attest_lite/device_attestQuerry_posix/Test.json
0 → 100644
浏览文件 @
fac1d5f6
{
"description"
:
"Config for kernel_lite test cases"
,
"environment"
:
[
{
"type"
:
"device"
,
"label"
:
"ipcamera"
}
],
"kits"
:
[
{
"type"
:
"MountKit"
,
"server"
:
"NfsServer"
,
"mount"
:
[
{
"source"
:
"testcases/xts"
,
"target"
:
"/test_root/xts"
}
]
}
],
"driver"
:
{
"type"
:
"CppTestLite"
,
"execute"
:
"/test_root/xts/ActsDeviceAttestQuerryTest.bin"
}
}
\ No newline at end of file
xts_lite/device_attest_lite/device_attestQuerry_posix/src/device_attest_querry.cpp
0 → 100644
浏览文件 @
fac1d5f6
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include <stdio.h>
#include "gtest/gtest.h"
#include "devattest_interface.h"
#define DEVATTEST_INIT -2
#define DEVATTEST_SUCCESS 0
using
namespace
std
;
using
namespace
testing
::
ext
;
typedef
enum
{
SOFTWARE_RESULT_VERSIONID
,
SOFTWARE_RESULT_PATCHLEVEL
,
SOFTWARE_RESULT_ROOTHASH
,
SOFTWARE_RESULT_PCID
,
SOFTWARE_RESULT_RESERVE
,
}
SOFTWARE_RESULT_DETAIL_TYPE
;
class
DeviceAttestQuerryTest
:
public
testing
::
Test
{
public:
bool
AttestStatusNumberValid
(
int32_t
attestStatusNumber
)
{
if
(
attestStatusNumber
<
DEVATTEST_INIT
||
attestStatusNumber
>
DEVATTEST_SUCCESS
)
{
return
false
;
}
return
true
;
}
::
testing
::
AssertionResult
AttestStatusValid
(
AttestResultInfo
attestResultInfo
)
{
bool
result
=
true
;
string
failString
;
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
authResult
))
{
failString
+=
string
(
" authResult is "
)
+
to_string
(
attestResultInfo
.
authResult
);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResult
))
{
failString
+=
string
(
" softwareResult is "
)
+
to_string
(
attestResultInfo
.
softwareResult
);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_VERSIONID
]))
{
failString
+=
string
(
" versionResult is "
)
+
to_string
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_VERSIONID
]);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PATCHLEVEL
]))
{
failString
+=
string
(
" patchResult is "
)
+
to_string
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PATCHLEVEL
]);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_ROOTHASH
]))
{
failString
+=
string
(
" roothashResult is "
)
+
to_string
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_ROOTHASH
]);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PCID
]))
{
failString
+=
string
(
" pcidResult is "
)
+
to_string
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PCID
]);
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_RESERVE
]))
{
failString
+=
string
(
" reserveResult is "
)
+
to_string
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_RESERVE
]);
result
=
false
;
}
if
(
attestResultInfo
.
authResult
==
DEVATTEST_SUCCESS
)
{
if
(
attestResultInfo
.
ticketLength
<=
0
)
{
failString
+=
string
(
" ticketLength is "
)
+
to_string
(
attestResultInfo
.
ticketLength
);
result
=
false
;
}
if
(
attestResultInfo
.
ticket
==
""
)
{
failString
+=
string
(
" ticket is empty"
);
result
=
false
;
}
}
if
(
result
)
{
return
::
testing
::
AssertionSuccess
();
}
else
{
return
::
testing
::
AssertionFailure
()
<<
failString
.
c_str
();
}
}
protected:
static
void
SetUpTestCase
(
void
)
{}
static
void
TearDownTestCase
(
void
)
{}
virtual
void
SetUp
()
{}
virtual
void
TearDown
()
{}
};
/**
* @tc.number : Sub_Device_Attest_Test_0200
* @tc.name : HiLog::Warn parameter legal test (Cortex-A, C)
* @tc.desc : [C- SOFTWARE -0200]
*/
HWTEST_F
(
DeviceAttestQuerryTest
,
subDeviceAttestTest0200
,
Function
|
MediumTest
|
Level1
)
{
int32_t
ret
=
DEVATTEST_SUCCESS
;
AttestResultInfo
attestResultInfo
=
{
0
};
attestResultInfo
.
ticket
=
NULL
;
printf
(
"[CLIENT MAIN] query.
\n
"
);
ret
=
GetAttestStatus
(
&
attestResultInfo
);
EXPECT_EQ
(
ret
,
DEVATTEST_SUCCESS
);
EXPECT_EQ
(
AttestStatusValid
(
attestResultInfo
),
true
);
}
/**
* @tc.number : Sub_Device_Attest_Test_0300
* @tc.name : HiLog::Warn parameter legal test (Cortex-A, C)
* @tc.desc : [C- SOFTWARE -0200]
*/
HWTEST_F
(
DeviceAttestQuerryTest
,
subDeviceAttestTest0300
,
Function
|
MediumTest
|
Level1
)
{
int32_t
ret
=
DEVATTEST_SUCCESS
;
ret
=
StartDevAttestTask
();
printf
(
"[CLIENT MAIN] StartDevAttestTask ret:%d.
\n
"
,
ret
);
EXPECT_EQ
(
ret
,
DEVATTEST_SUCCESS
);
AttestResultInfo
attestResultInfo
=
{
0
};
attestResultInfo
.
ticket
=
NULL
;
printf
(
"[CLIENT MAIN] query.
\n
"
);
ret
=
GetAttestStatus
(
&
attestResultInfo
);
printf
(
"[CLIENT MAIN] wrong. ret:%d
\n
"
,
ret
);
#ifdef __LINUX__
EXPECT_EQ
(
ret
,
DEVATTEST_SUCCESS
);
#else
EXPECT_FALSE
(
ret
==
DEVATTEST_SUCCESS
);
#endif
}
xts_lite/device_attest_lite/device_attestStart_hal/BUILD.gn
0 → 100644
浏览文件 @
fac1d5f6
# Copyright (c) 2023 Huawei Device Co., Ltd.
# 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("//test/xts/tools/lite/build/suite_lite.gni")
hctest_suite("ActsDeviceAttestTest") {
suite_name = "acts"
sources = [ "src/device_attest.c" ]
include_dirs = [
"src",
"//test/xts/device_attest_lite/interfaces/kit/js/include",
"//test/xts/device_attest_lite/interfaces/innerkits",
"//test/xts/device_attest_lite/framework/mini",
]
if (board_toolchain_type != "iccarm") {
cflags = [ "-Wno-error" ]
}
}
xts_lite/device_attest_lite/device_attestStart_hal/Test.tmpl
0 → 100644
浏览文件 @
fac1d5f6
{
"description": "Config for $module test cases",
"environment": [
{
"type": "device",
"label": "wifiiot"
}
],
"kits": [
{
"type": "DeployKit",
"timeout": "20000",
"burn_file": "$subsystem/$module.bin"
}
],
"driver": {
"type": "CTestLite"
}
}
\ No newline at end of file
xts_lite/device_attest_lite/device_attestStart_hal/src/device_attest.c
0 → 100644
浏览文件 @
fac1d5f6
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "hctest.h"
#include "devattest_interface.h"
#define DEVATTEST_INIT -2
#define DEVATTEST_SUCCESS 0
typedef
enum
{
SOFTWARE_RESULT_VERSIONID
,
SOFTWARE_RESULT_PATCHLEVEL
,
SOFTWARE_RESULT_ROOTHASH
,
SOFTWARE_RESULT_PCID
,
SOFTWARE_RESULT_RESERVE
,
}
SOFTWARE_RESULT_DETAIL_TYPE
;
/**
* @tc.desc : register a test suite, this suite is used to test basic flow and interface dependency
* @param : subsystem name is dfx
* @param : module name is dfxlite
* @param : test suit name is DfxFuncTestSuite
*/
LITE_TEST_SUIT
(
device_attest
,
device_attest_lite
,
DeviceAttestFuncTestSuite
);
/**
* @tc.setup : setup for all testcases
* @return : setup result, TRUE is success, FALSE is fail
*/
static
BOOL
DeviceAttestFuncTestSuiteSetUp
(
void
)
{
return
TRUE
;
}
/**
* @tc.teardown : teardown for all testcases
* @return : teardown result, TRUE is success, FALSE is fail
*/
static
BOOL
DeviceAttestFuncTestSuiteTearDown
(
void
)
{
printf
(
"+-------------------------------------------+
\n
"
);
return
TRUE
;
}
bool
AttestStatusNumberValid
(
int32_t
attestStatusNumber
)
{
if
(
attestStatusNumber
<
DEVATTEST_INIT
||
attestStatusNumber
>
DEVATTEST_SUCCESS
)
{
return
false
;
}
return
true
;
}
bool
AttestStatusValid
(
AttestResultInfo
attestResultInfo
)
{
bool
result
=
true
;
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
authResult
))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResult
))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_VERSIONID
]))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PATCHLEVEL
]))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_ROOTHASH
]))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_PCID
]))
{
result
=
false
;
}
if
(
!
AttestStatusNumberValid
(
attestResultInfo
.
softwareResultDetail
[
SOFTWARE_RESULT_RESERVE
]))
{
result
=
false
;
}
if
(
attestResultInfo
.
authResult
==
DEVATTEST_SUCCESS
)
{
if
(
attestResultInfo
.
ticketLength
<=
0
)
{
result
=
false
;
}
if
(
attestResultInfo
.
ticket
==
""
)
{
result
=
false
;
}
}
if
(
result
)
{
return
true
;
}
else
{
return
false
;
}
}
/**
* @tc.number : SUB_Device_Attest_0100
* @tc.name : StartDevAttestTask test
* @tc.desc : [C- SOFTWARE -0200]
* @tc.size : MEDIUM
* @tc.type : RELI
* @tc.level : Level 0
*/
LITE_TEST_CASE
(
DeviceAttestFuncTestSuite
,
subDeviceAttest0100
,
LEVEL0
)
{
int32_t
ret
=
DEVATTEST_SUCCESS
;
ret
=
StartDevAttestTask
();
TEST_ASSERT_EQUAL_INT
(
ret
,
DEVATTEST_SUCCESS
);
};
/**
* @tc.number : SUB_Device_Attest_0200
* @tc.name : GetAttestStatus test
* @tc.desc : [C- SOFTWARE -0200]
* @tc.size : MEDIUM
* @tc.type : RELI
* @tc.level : Level 0
*/
LITE_TEST_CASE
(
DeviceAttestFuncTestSuite
,
subDeviceAttest0200
,
LEVEL0
)
{
int32_t
ret
=
DEVATTEST_SUCCESS
;
AttestResultInfo
attestResultInfo
=
{
0
};
attestResultInfo
.
ticket
=
NULL
;
ret
=
GetAttestStatus
(
&
attestResultInfo
);
TEST_ASSERT_EQUAL_INT
(
ret
,
DEVATTEST_SUCCESS
);
TEST_ASSERT_EQUAL_INT
(
AttestStatusValid
(
attestResultInfo
),
true
);
};
RUN_TEST_SUITE
(
DeviceAttestFuncTestSuite
);
xts_lite/device_attest_lite/device_attestStart_posix/BUILD.gn
0 → 100644
浏览文件 @
fac1d5f6
# Copyright (c) 2023 Huawei Device Co., Ltd.
# 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("//test/xts/tools/lite/build/suite_lite.gni")
hcpptest_suite("ActsDeviceAttestStartTest") {
suite_name = "acts"
sources = [ "src/device_attest_start.cpp" ]
include_dirs = [
"src",
"//test/xts/device_attest_lite/interfaces/kit/js/include",
"//test/xts/device_attest_lite/interfaces/innerkits",
"//test/xts/device_attest_lite/framework/small",
]
deps = [ "//test/xts/device_attest_lite/framework:devattest_client" ]
cflags = [ "-Wno-error" ]
ldflags = [
"-lstdc++",
"-lm",
"-lpthread",
]
}
xts_lite/device_attest_lite/device_attestStart_posix/Test.json
0 → 100644
浏览文件 @
fac1d5f6
{
"description"
:
"Config for kernel_lite test cases"
,
"environment"
:
[
{
"type"
:
"device"
,
"label"
:
"ipcamera"
}
],
"kits"
:
[
{
"type"
:
"MountKit"
,
"server"
:
"NfsServer"
,
"mount"
:
[
{
"source"
:
"testcases/xts"
,
"target"
:
"/test_root/xts"
}
]
}
],
"driver"
:
{
"type"
:
"CppTestLite"
,
"execute"
:
"/test_root/xts/ActsDeviceAttestStartTest.bin"
}
}
\ No newline at end of file
xts_lite/device_attest_lite/device_attestStart_posix/src/device_attest_start.cpp
0 → 100644
浏览文件 @
fac1d5f6
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include <stdio.h>
#include "gtest/gtest.h"
#include "devattest_interface.h"
#define ATTEST_SOFTWARE_RESULT_SIZE 5
using
namespace
std
;
using
namespace
testing
::
ext
;
class
DeviceAttestStartTest
:
public
testing
::
Test
{
protected:
static
void
SetUpTestCase
(
void
)
{}
static
void
TearDownTestCase
(
void
)
{}
virtual
void
SetUp
()
{}
virtual
void
TearDown
()
{
sleep
(
4
);
}
};
/**
* @tc.number : Sub_Device_Attest_Test_0100
* @tc.name : HiLog::Info parameter legal test (Cortex-A, C)
* @tc.desc : [C- SOFTWARE -0200]
*/
HWTEST_F
(
DeviceAttestStartTest
,
subDeviceAttestTest0100
,
Function
|
MediumTest
|
Level1
)
{
int32_t
ret
=
DEVATTEST_SUCCESS
;
ret
=
StartDevAttestTask
();
printf
(
"[CLIENT MAIN] StartDevAttestTask ret:%d.
\n
"
,
ret
);
EXPECT_EQ
(
ret
,
DEVATTEST_SUCCESS
);
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录