Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Xts Acts
提交
a7c784bf
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看板
未验证
提交
a7c784bf
编写于
9月 16, 2022
作者:
O
openharmony_ci
提交者:
Gitee
9月 16, 2022
浏览文件
操作
浏览文件
下载
差异文件
!5496 Add toolchain
Merge pull request !5496 from FondMemoryVVV/toolchain
上级
1e24752c
02f647c4
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
572 addition
and
1 deletion
+572
-1
commonlibrary/BUILD.gn
commonlibrary/BUILD.gn
+4
-1
commonlibrary/toolchain/BUILD.gn
commonlibrary/toolchain/BUILD.gn
+123
-0
commonlibrary/toolchain/libc-test/BUILD.gn
commonlibrary/toolchain/libc-test/BUILD.gn
+54
-0
commonlibrary/toolchain/libc-test/Test.json
commonlibrary/toolchain/libc-test/Test.json
+30
-0
commonlibrary/toolchain/libc-test/include/getfiles.cpp
commonlibrary/toolchain/libc-test/include/getfiles.cpp
+41
-0
commonlibrary/toolchain/libc-test/include/gettestfiles.cpp
commonlibrary/toolchain/libc-test/include/gettestfiles.cpp
+44
-0
commonlibrary/toolchain/libc-test/include/runtest.h
commonlibrary/toolchain/libc-test/include/runtest.h
+28
-0
commonlibrary/toolchain/libc-test/include/setrlim.cpp
commonlibrary/toolchain/libc-test/include/setrlim.cpp
+44
-0
commonlibrary/toolchain/libc-test/src/toolchaintest.cpp
commonlibrary/toolchain/libc-test/src/toolchaintest.cpp
+141
-0
commonlibrary/toolchain/libc-test/tar_files.py
commonlibrary/toolchain/libc-test/tar_files.py
+63
-0
未找到文件。
commonlibrary/BUILD.gn
浏览文件 @
a7c784bf
...
...
@@ -15,6 +15,9 @@ import("//test/xts/tools/build/suite.gni")
group("commonlibrary") {
testonly = true
if (is_standard_system) {
deps = [ "ets_utils:ets_utils" ]
deps = [
"ets_utils:ets_utils",
"toolchain:toolchain",
]
}
}
commonlibrary/toolchain/BUILD.gn
0 → 100644
浏览文件 @
a7c784bf
# Copyright (C) 2021 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("//build/ohos_var.gni")
import("//test/xts/tools/build/suite.gni")
group("toolchain") {
testonly = true
deps = [ "//third_party/musl:libctest" ]
if (is_standard_system) {
deps += [ ":tar_dllib" ]
}
}
action("tar_testcases") {
testonly = true
deps = [
"libc-test:ActToolChainTest",
"//third_party/musl:libctest",
]
project_dir = rebase_path(".")
print("project_dir-58:", project_dir)
project_dird = rebase_path("tar_files.py", ".", root_out_dir)
print("project_dird-60:", project_dird)
project_dirf = project_dir + "/" + project_dird
print("project_dirf-64:", project_dirf)
test_path = string_replace(project_dirf, "/tar_files.py", "")
script = rebase_path(
"//test/xts/acts/commonlibrary/toolchain/libc-test/tar_files.py")
_outputs = [ "$target_out_dir/libc-test.tar" ]
outputs = _outputs
input_path = rebase_path("$test_path/tests/unittest/libc-test")
output_path = rebase_path("$test_path/suites/acts/testcases/libc-test.tar")
print("root_build_dir-49", root_build_dir)
args = [
"--input_path",
input_path,
"--output_path",
output_path,
"--temp_path",
"./libc-test",
]
}
action("tar_dllib") {
testonly = true
deps = [ ":tar_testcases" ]
project_dir = rebase_path(".")
print("project_dir-58:", project_dir)
project_dird = rebase_path("tar_files.py", ".", root_out_dir)
print("project_dird-60:", project_dird)
project_dirf = project_dir + "/" + project_dird
print("project_dirf-64:", project_dirf)
dllib_path = string_replace(project_dirf, "/tar_files.py", "")
script = rebase_path(
"//test/xts/acts/commonlibrary/toolchain/libc-test/tar_files.py")
if (target_cpu == "arm") {
_outputs = [ "$target_out_dir/libc-test-lib.tar" ]
outputs = _outputs
input_path = rebase_path("$dllib_path/musl/libc-test-lib")
output_path =
rebase_path("$dllib_path/suites/acts/testcases/libc-test-lib.tar")
print("root_build_dir-49", root_build_dir)
args = [
"--input_path",
input_path,
"--output_path",
output_path,
"--temp_path",
"./libc-test-lib",
]
} else if (target_cpu == "arm64") {
_outputs = [ "$target_out_dir/libc-test-lib.tar" ]
outputs = _outputs
input_path = rebase_path("$dllib_path/musl/libc-test-lib")
output_path =
rebase_path("$dllib_path/suites/acts/testcases/libc-test-lib.tar")
print("root_build_dir-49", root_build_dir)
args = [
"--input_path",
input_path,
"--output_path",
output_path,
"--temp_path",
"./libc-test-lib",
]
} else {
_outputs = [ "" ]
outputs = _outputs
input_path = rebase_path("")
output_path = rebase_path("")
print("root_build_dir-49", root_build_dir)
args = [
"--input_path",
input_path,
"--output_path",
output_path,
"--temp_path",
"./libc-test-lib",
]
}
}
commonlibrary/toolchain/libc-test/BUILD.gn
0 → 100644
浏览文件 @
a7c784bf
# Copyright (C) 2021 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("//build/test.gni")
import("//test/xts/tools/build/suite.gni")
#module_output_path = "hits/huks_standard"
########################################################
config("module_private_config") {
visibility = [ ":*" ]
include_dirs = [
"//utils/native/base/include",
"//third_party/bounds_checking_function/include",
"//third_party/musl/porting/linux/user/include",
"//test/xts/acts/security_lite/huks/common/include",
]
}
########################################################
ohos_moduletest_suite("ActToolChainTest") {
configs = [ ":module_private_config" ]
cflags_cc = [ "-DHILOG_ENABLE" ]
defines = [ "_STANDARD_SYSTEM_" ]
sources = [
"include/getfiles.cpp",
"include/setrlim.cpp",
"src/toolchaintest.cpp",
]
include_dirs = [
"//utils/native/base/include",
"//third_party/bounds_checking_function/include",
"//third_party/musl/porting/linux/user/include/",
"//third_party/musl/porting/linux/user/src/sched",
"/third_party/musl/libc-test/src/commom",
"./include",
]
deps = [
"//third_party/bounds_checking_function:libsec_static",
"//utils/native/base:utils",
]
}
commonlibrary/toolchain/libc-test/Test.json
0 → 100644
浏览文件 @
a7c784bf
{
"kits"
:
[
{
"push"
:
[
"ActToolChainTest->/data/local/tmp/ActToolChainTest"
,
"libc-test.tar->/data/local/tmp/libc-test.tar"
,
"libc-test-lib.tar->/data/local/tmp/libc-test-lib.tar"
],
"type"
:
"PushKit"
,
"post-push"
:
[
"mkdir /tmp"
,
"mkdir /dev/shm"
,
"mkdir /src"
,
"mkdir /src/functional"
,
"tar -xf /data/local/tmp/libc-test.tar -C /data/local/tmp/"
,
"tar -xf /data/local/tmp/libc-test-lib.tar -C /data/local/tmp/"
,
"chmod a+x -R /data/local/tmp/libc-test-lib"
,
"chmod a+x -R /data/local/tmp/libc-test"
]
}
],
"driver"
:
{
"native-test-timeout"
:
"120000"
,
"type"
:
"CppTest"
,
"module-name"
:
"ActToolChainTest"
,
"runtime-hint"
:
"100s"
,
"native-test-device-path"
:
"/data/local/tmp"
},
"description"
:
"Configuration for ActToolChainTest Tests"
}
\ No newline at end of file
commonlibrary/toolchain/libc-test/include/getfiles.cpp
0 → 100644
浏览文件 @
a7c784bf
/*
* Copyright (C) 2022 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 <iostream>
#include <vector>
#include <cstring>
#include <dirent.h>
#include "gettestfiles.cpp"
#include "runtest.h"
namespace
OHOS
{
using
namespace
std
;
static
vector
<
std
::
string
>
filenames
;
std
::
vector
<
std
::
string
>
runtest
::
GetFileNames
(
std
::
string
path
)
{
vector
<
string
>
tempName
;
GetTestNames
(
path
,
tempName
);
for
(
size_t
i
=
0
;
i
<
tempName
.
size
();
i
++
)
{
if
((
tempName
[
i
].
find
(
"stat"
,
path
.
length
()
-
1
)
!=
-
1
)
||
(
tempName
[
i
].
find
(
"sem_close-unmap"
,
path
.
length
()
-
1
)
!=
-
1
)
||
(
tempName
[
i
].
find
(
"runtest"
,
path
.
length
()
-
1
)
!=
-
1
))
{
continue
;
}
filenames
.
push_back
(
tempName
[
i
]);
}
return
filenames
;
}
}
// namespace OHOS
\ No newline at end of file
commonlibrary/toolchain/libc-test/include/gettestfiles.cpp
0 → 100644
浏览文件 @
a7c784bf
/*
* Copyright (C) 2022 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 <iostream>
#include <vector>
#include <cstring>
#include <dirent.h>
#include "runtest.h"
static
void
GetTestNames
(
std
::
string
path
,
std
::
vector
<
std
::
string
>&
tempName
)
{
DIR
*
pDir
;
struct
dirent
*
ptr
;
std
::
string
p
;
if
(
!
(
pDir
=
opendir
(
path
.
c_str
())))
{
std
::
cout
<<
"Folder doesn't Exist!"
<<
std
::
endl
;
return
;
}
while
((
ptr
=
readdir
(
pDir
))
!=
nullptr
)
{
if
(
ptr
->
d_type
==
DT_DIR
)
{
if
(
strcmp
(
ptr
->
d_name
,
"."
)
!=
0
&&
strcmp
(
ptr
->
d_name
,
".."
)
!=
0
)
{
GetTestNames
(
path
+
"/"
+
ptr
->
d_name
,
tempName
);
}
}
else
{
if
(
strcmp
(
ptr
->
d_name
,
"."
)
!=
0
&&
strcmp
(
ptr
->
d_name
,
".."
)
!=
0
)
{
tempName
.
push_back
(
path
+
"/"
+
ptr
->
d_name
);
}
}
}
closedir
(
pDir
);
}
\ No newline at end of file
commonlibrary/toolchain/libc-test/include/runtest.h
0 → 100644
浏览文件 @
a7c784bf
/*
* Copyright (C) 2022 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.
*/
#ifndef TOOLCHAIN_RUNTEST_H
#define TOOLCHAIN_RUNTEST_H
#include <iostream>
#include <string>
#include <vector>
namespace
OHOS
{
class
runtest
{
public:
static
int
t_setrlim
(
int
r
,
long
lim
);
static
std
::
vector
<
std
::
string
>
GetFileNames
(
std
::
string
path
);
};
}
// namespace OHOS
#endif // TOOLCHAIN_LIBC_TEST_INCLUDE_RUNTEST_H_
commonlibrary/toolchain/libc-test/include/setrlim.cpp
0 → 100644
浏览文件 @
a7c784bf
/*
* Copyright (C) 2021 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 <cstring>
#include <cerrno>
#include <cstdio>
#include <sys/resource.h>
#include "runtest.h"
namespace
OHOS
{
int
runtest
::
t_setrlim
(
int
r
,
long
lim
)
{
struct
rlimit
rl
;
//Gets the current stack size
if
(
getrlimit
(
r
,
&
rl
))
{
printf
(
"getrlimit %d: %s
\n
"
,
r
,
strerror
(
errno
));
return
-
1
;
}
if
(
lim
>
rl
.
rlim_max
)
{
return
-
1
;
}
if
(
lim
==
rl
.
rlim_max
&&
lim
==
rl
.
rlim_cur
)
{
return
0
;
}
rl
.
rlim_max
=
lim
;
rl
.
rlim_cur
=
lim
;
if
(
setrlimit
(
r
,
&
rl
))
{
printf
(
"setrlimit(%d, %ld): %s
\n
"
,
r
,
lim
,
strerror
(
errno
));
return
-
1
;
}
return
0
;
}
}
// namespace OHOS
\ No newline at end of file
commonlibrary/toolchain/libc-test/src/toolchaintest.cpp
0 → 100644
浏览文件 @
a7c784bf
/*
* Copyright (C) 2022 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 <iostream>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <ctime>
#include <cstdio>
#include <vector>
#include <csignal>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "gtest/gtest.h"
#include "runtest.h"
using
namespace
std
;
using
namespace
testing
::
ext
;
using
namespace
testing
;
namespace
OHOS
{
class
toolchaintest
:
public
::
testing
::
TestWithParam
<
string
>
{};
static
string
filepath
=
"/data/local/tmp/libc-test/src"
;
static
vector
<
std
::
string
>
temp
=
runtest
::
GetFileNames
(
filepath
);
volatile
int
t_status
=
0
;
static
void
handler
(
int
sig
)
{
}
static
int
start
(
const
char
*
argvs
)
{
int
pid
,
space_size
=
100
*
1024
;
//Create a child process
//Set the process stack space
pid
=
fork
();
if
(
pid
==
0
)
{
runtest
::
t_setrlim
(
RLIMIT_STACK
,
space_size
);
//Overloading the subprocess space
int
exe
=
execl
(
argvs
,
"strptime"
,
nullptr
);
printf
(
"exe:%d %s exec failed: %s
\n
"
,
exe
,
argvs
,
strerror
(
errno
));
exit
(
1
);
}
return
pid
;
}
static
int
runTests
(
const
char
*
argvs
)
{
int
timeoutsec
=
5
,
timeout
=
0
;
int
status
,
pid
;
sigset_t
set
;
void
(
*
retfunc
)(
int
);
//signal set
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
SIGCHLD
);
sigprocmask
(
SIG_BLOCK
,
&
set
,
nullptr
);
retfunc
=
signal
(
SIGCHLD
,
handler
);
if
(
retfunc
==
SIG_ERR
)
{
printf
(
"signal triggering failed:%s
\n
"
,
strerror
(
errno
));
}
pid
=
start
(
argvs
);
//The function system call failed
if
(
pid
==
-
1
)
{
printf
(
"%s fork failed: %s
\n
"
,
argvs
,
strerror
(
errno
));
printf
(
"FAIL %s [internal]
\n
"
,
argvs
);
return
-
1
;
}
struct
timespec
tp
;
//Maximum blocking time
tp
.
tv_sec
=
timeoutsec
;
tp
.
tv_nsec
=
0
;
if
(
sigtimedwait
(
&
set
,
nullptr
,
&
tp
)
==
-
1
)
{
//Call it again
if
(
errno
==
EAGAIN
)
{
timeout
=
1
;
}
else
{
printf
(
"%s sigtimedwait failed: %s
\n
"
,
argvs
,
strerror
(
errno
));
}
if
(
kill
(
pid
,
SIGKILL
)
==
-
1
)
{
printf
(
"%s kill failed: %s
\n
"
,
argvs
,
strerror
(
errno
));
}
}
//Waiting for the process to stop
if
(
waitpid
(
pid
,
&
status
,
0
)
!=
pid
)
{
printf
(
"%s waitpid failed: %s
\n
"
,
argvs
,
strerror
(
errno
));
printf
(
"FAIL %s [internal]
\n
"
,
argvs
);
return
-
1
;
}
//Process state
if
(
WIFEXITED
(
status
))
{
//The right exit
if
(
WEXITSTATUS
(
status
)
==
0
)
{
//operate successfully
return
t_status
;
}
printf
(
"FAIL %s [status %d]
\n
"
,
argvs
,
WEXITSTATUS
(
status
));
}
else
if
(
timeout
)
{
printf
(
"FAIL %s [timed out]
\n
"
,
argvs
);
}
else
if
(
WIFSIGNALED
(
status
))
{
printf
(
"FAIL %s [signal %s]
\n
"
,
argvs
,
strsignal
(
WTERMSIG
(
status
)));
}
else
{
printf
(
"FAIL %s [unknown]
\n
"
,
argvs
);
}
return
1
;
}
/**
* @tc.name : toolchaintest.LibcTest
* @tc.desc : start test
* @tc.level : Level 3
*/
HWTEST_P
(
toolchaintest
,
LibcTest
,
Function
|
MediumTest
|
Level3
)
{
int
ret
;
string
testName
=
GetParam
();
ret
=
runTests
(
testName
.
c_str
());
if
(
ret
==
0
)
{
EXPECT_EQ
(
0
,
ret
)
<<
"test "
<<
testName
<<
" succeed"
<<
endl
;
}
else
{
EXPECT_EQ
(
1
,
ret
)
<<
"test "
<<
testName
<<
" failed"
<<
endl
;
EXPECT_EQ
(
-
1
,
ret
)
<<
"test "
<<
testName
<<
" failed"
<<
endl
;
}
}
INSTANTIATE_TEST_SUITE_P
(
libcTest
,
toolchaintest
,
testing
::
ValuesIn
(
temp
.
begin
(),
temp
.
end
()));
}
// namespace OHOS
\ No newline at end of file
commonlibrary/toolchain/libc-test/tar_files.py
0 → 100755
浏览文件 @
a7c784bf
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Copyright (c) 2020-2021 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
os
import
argparse
import
tarfile
import
shutil
copyFileCounts
=
0
def
copyFiles
(
sourceDir
,
targetDir
):
global
copyFileCounts
for
f
in
os
.
listdir
(
sourceDir
):
sourceF
=
os
.
path
.
join
(
sourceDir
,
f
)
targetF
=
os
.
path
.
join
(
targetDir
,
f
)
if
not
os
.
path
.
isfile
(
sourceF
):
if
os
.
path
.
isdir
(
sourceF
):
copyFiles
(
sourceF
,
targetF
)
elif
os
.
path
.
isfile
(
sourceF
):
if
os
.
path
.
exists
(
targetDir
):
copyFileCounts
+=
1
open
(
targetF
,
"wb"
).
write
(
open
(
sourceF
,
"rb"
).
read
())
elif
not
os
.
path
.
exists
(
targetDir
):
os
.
makedirs
(
targetDir
)
copyFileCounts
+=
1
open
(
targetF
,
"wb"
).
write
(
open
(
sourceF
,
"rb"
).
read
())
def
make_targz_one_by_one
(
output_filename
,
source_dir
):
tar
=
tarfile
.
open
(
output_filename
,
"w"
)
for
root
,
dir
,
files
in
os
.
walk
(
source_dir
):
for
file
in
files
:
pathfile
=
os
.
path
.
join
(
root
,
file
)
tar
.
add
(
pathfile
)
tar
.
close
()
if
__name__
==
"__main__"
:
parser
=
argparse
.
ArgumentParser
(
description
=
'manual to this script'
)
parser
.
add_argument
(
"--input_path"
,
type
=
str
,
default
=
"0"
)
parser
.
add_argument
(
"--output_path"
,
type
=
str
,
default
=
"0"
)
parser
.
add_argument
(
"--temp_path"
,
type
=
str
,
default
=
"0"
)
args
=
parser
.
parse_args
()
print
(
args
.
input_path
)
print
(
args
.
output_path
)
print
(
args
.
temp_path
)
copyFiles
(
args
.
input_path
,
args
.
temp_path
)
make_targz_one_by_one
(
args
.
output_path
,
args
.
temp_path
)
shutil
.
rmtree
(
args
.
temp_path
)
#delete middle files
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录