未验证 提交 f5c2c720 编写于 作者: O openharmony_ci 提交者: Gitee

!6177 【OpenHarmony开源贡献者计划2022】[英文]相关格式及表达问题

Merge pull request !6177 from king_he/0630-1
...@@ -58,7 +58,8 @@ subsystem # Subsystem ...@@ -58,7 +58,8 @@ subsystem # Subsystem
... ...
``` ```
> **Note:** Test cases are classified into common test cases and device-specific test cases. You are advised to place common test cases in the **common** directory and device-specific test cases in the directories of the related devices. > **NOTE**<br>
> Test cases are classified into common test cases and device-specific test cases. You are advised to place common test cases in the **common** directory and device-specific test cases in the directories of the related devices.
### Writing Test Cases ### Writing Test Cases
This test framework supports test cases written in multiple programming languages and provides different templates for different languages. This test framework supports test cases written in multiple programming languages and provides different templates for different languages.
...@@ -196,7 +197,8 @@ Example: ...@@ -196,7 +197,8 @@ Example:
// Set a teardown function, which will be called after each test case. // Set a teardown function, which will be called after each test case.
} }
``` ```
> **Note**: When defining a test suite, ensure that the test suite name is the same as the target to build and uses the upper camel case style. > **NOTE**<br>
> When defining a test suite, ensure that the test suite name is the same as the target to build and uses the upper camel case style.
5. Add implementation of the test cases, including test case comments and logic. 5. Add implementation of the test cases, including test case comments and logic.
``` ```
...@@ -217,30 +219,30 @@ Example: ...@@ -217,30 +219,30 @@ Example:
``` ```
The following test case templates are provided for your reference. The following test case templates are provided for your reference.
| Type| Description| | Type | Description |
| ------------| ------------| | ------------ | ------------ |
| HWTEST(A,B,C)| Use this template if the test case execution does not depend on setup or teardown.| | HWTEST(A,B,C) | Use this template if the test case execution does not depend on setup or teardown. |
| HWTEST_F(A,B,C)| Use this template if the test case execution (excluding parameters) depends on setup and teardown.| | HWTEST_F(A,B,C) | Use this template if the test case execution (excluding parameters) depends on setup and teardown. |
| HWTEST_P(A,B,C)| Use this template if the test case execution (including parameters) depends on setup and teardown.| | HWTEST_P(A,B,C) | Use this template if the test case execution (including parameters) depends on setup and teardown. |
In the template names: In the template names:
- *A* indicates the test suite name. - *A* indicates the test suite name.
- *B* indicates the test case name, which is in the *Function*\_*No.* format. The *No.* is a three-digit number starting from **001**. - *B* indicates the test case name, which is in the *Function*\_*No.* format. The *No.* is a three-digit number starting from **001**.
- *C* indicates the test case level. There are five test case levels: guard-control level 0 and non-guard-control level 1 to level 4. Of levels 1 to 4, a smaller value indicates a more important function verified by the test case. - *C* indicates the test case level. There are five test case levels: guard-control level 0 and non-guard-control level 1 to level 4. Of levels 1 to 4, a smaller value indicates a more important function verified by the test case.
**Note**: Note the following:
- The expected result of each test case must have an assertion. - The expected result of each test case must have an assertion.
- The test case level must be specified. - The test case level must be specified.
- It is recommended that the test be implemented step by step according to the template. - It is recommended that the test be implemented step by step according to the template.
- The comment must contain the test case name, description, type, and requirement number, which are in the @tc.*xxx*: *value* format. The test case type @**tc.type** can be any of the following: - The comment must contain the test case name, description, type, and requirement number, which are in the @tc.*xxx*: *value* format. The test case type @**tc.type** can be any of the following:
| Test Case Type|Code| | Test Case Type | Code |
| ------------|------------| | ------------ | ---------- |
|Function test|FUNC| | Function test | FUNC |
|Performance test|PERF| | Performance test | PERF |
|Reliability test|RELI| | Reliability test | RELI |
|Security test|SECU| | Security test | SECU |
|Fuzz test|FUZZ| | Fuzz test | FUZZ |
**JavaScript Test Case Example** **JavaScript Test Case Example**
...@@ -416,18 +418,24 @@ The following provides templates for different languages for your reference. ...@@ -416,18 +418,24 @@ The following provides templates for different languages for your reference.
The procedure is as follows: The procedure is as follows:
1. Add comment information for the file header. 1. Add comment information for the file header.
``` ```
# Copyright (c) 2021 XXXX Device Co., Ltd. # Copyright (c) 2021 XXXX Device Co., Ltd.
``` ```
2. Import the build template. 2. Import the build template.
``` ```
import("//build/test.gni") import("//build/test.gni")
``` ```
3. Specify the file output path. 3. Specify the file output path.
``` ```
module_output_path = "subsystem_examples/calculator" module_output_path = "subsystem_examples/calculator"
``` ```
> **Note**: The output path is ***Part name*/*Module name***. > **NOTE**<br>
> The output path is ***Part name*/*Module name***.
4. Configure the directories for dependencies. 4. Configure the directories for dependencies.
...@@ -438,7 +446,8 @@ The following provides templates for different languages for your reference. ...@@ -438,7 +446,8 @@ The following provides templates for different languages for your reference.
include_dirs = [ "../../../include" ] include_dirs = [ "../../../include" ]
} }
``` ```
> **Note**: Generally, the dependency directories are configured here and directly referenced in the build script of the test case. > **NOTE**<br>
> Generally, the dependency directories are configured here and directly referenced in the build script of the test case.
5. Set the output build file for the test cases. 5. Set the output build file for the test cases.
...@@ -461,7 +470,8 @@ The following provides templates for different languages for your reference. ...@@ -461,7 +470,8 @@ The following provides templates for different languages for your reference.
} }
``` ```
> **Note:** Set the test type based on actual requirements. The following test types are available: > **NOTE**<br>
> Set the test type based on actual requirements. The following test types are available:
> - **ohos_unittest**: unit test > - **ohos_unittest**: unit test
> - **ohos_moduletest**: module test > - **ohos_moduletest**: module test
> - **ohos_systemtest**: system test > - **ohos_systemtest**: system test
...@@ -478,7 +488,8 @@ The following provides templates for different languages for your reference. ...@@ -478,7 +488,8 @@ The following provides templates for different languages for your reference.
deps = [":CalculatorSubTest"] deps = [":CalculatorSubTest"]
} }
``` ```
> **Note**: Grouping test cases by test type allows you to execute a specific type of test cases when required. > **NOTE**<br>
> Grouping test cases by test type allows you to execute a specific type of test cases when required.
- **Test case build file example (JavaScript)** - **Test case build file example (JavaScript)**
...@@ -519,7 +530,8 @@ The following provides templates for different languages for your reference. ...@@ -519,7 +530,8 @@ The following provides templates for different languages for your reference.
``` ```
module_output_path = "subsystem_examples/app_info" module_output_path = "subsystem_examples/app_info"
``` ```
> **Note**: The output path is ***Part name*/*Module name***. > **NOTE**<br>
> The output path is ***Part name*/*Module name***.
4. Set the output build file for the test cases. 4. Set the output build file for the test cases.
...@@ -527,7 +539,7 @@ The following provides templates for different languages for your reference. ...@@ -527,7 +539,7 @@ The following provides templates for different languages for your reference.
ohos_js_unittest("GetAppInfoJsTest") { ohos_js_unittest("GetAppInfoJsTest") {
} }
``` ```
> **Note:** > **NOTE**
>- Use the **ohos\_js\_unittest** template to define the JavaScript test suite. Pay attention to the difference between JavaScript and C++. >- Use the **ohos\_js\_unittest** template to define the JavaScript test suite. Pay attention to the difference between JavaScript and C++.
>- The file generated for the JavaScript test suite must be in .hap format and named after the test suite name defined here. The test suite name must end with **JsTest**. >- The file generated for the JavaScript test suite must be in .hap format and named after the test suite name defined here. The test suite name must end with **JsTest**.
...@@ -611,7 +623,8 @@ The following provides templates for different languages for your reference. ...@@ -611,7 +623,8 @@ The following provides templates for different languages for your reference.
deps = [ ":GetAppInfoJsTest" ] deps = [ ":GetAppInfoJsTest" ]
} }
``` ```
> **Note**: Grouping test cases by test type allows you to execute a specific type of test cases when required. > **NOTE**<br>
> Grouping test cases by test type allows you to execute a specific type of test cases when required.
#### Configuring ohos.build #### Configuring ohos.build
...@@ -632,7 +645,9 @@ Configure the part build file to associate with specific test cases. ...@@ -632,7 +645,9 @@ Configure the part build file to associate with specific test cases.
] ]
} }
``` ```
> **Note**: **test_list** contains the test cases of the corresponding module.
> **NOTE**<br>
> **test_list** contains the test cases of the corresponding module.
### Configuring Test Case Resources ### Configuring Test Case Resources
Test case resources include external file resources, such as image files, video files, and third-party libraries, required for test case execution. Test case resources include external file resources, such as image files, video files, and third-party libraries, required for test case execution.
...@@ -658,7 +673,7 @@ Perform the following steps: ...@@ -658,7 +673,7 @@ Perform the following steps:
resource_config_file = "//system/subsystem/partA/test/resource/calculator/ohos_test.xml" resource_config_file = "//system/subsystem/partA/test/resource/calculator/ohos_test.xml"
} }
``` ```
>**Note:** >**NOTE**
>- **target_name** indicates the test suite name defined in the **BUILD.gn** file in the **test** directory.**preparer** indicates the action to perform before the test suite is executed. >- **target_name** indicates the test suite name defined in the **BUILD.gn** file in the **test** directory.**preparer** indicates the action to perform before the test suite is executed.
>- **src="res"** indicates that the test resources are in the **resource** directory under the **test** directory. **src="out"** indicates that the test resources are in the **out/release/$(*part*)** directory. >- **src="res"** indicates that the test resources are in the **resource** directory under the **test** directory. **src="out"** indicates that the test resources are in the **out/release/$(*part*)** directory.
...@@ -711,7 +726,8 @@ Before executing test cases, you need to modify the configuration based on the d ...@@ -711,7 +726,8 @@ Before executing test cases, you need to modify the configuration based on the d
</NFS> </NFS>
</user_config> </user_config>
``` ```
>**Note**: If HDC is connected to the device before the test cases are executed, you only need to configure the device IP address and port number, and retain the default settings for other parameters. > **NOTE**<br>
> If HDC is connected to the device before the test cases are executed, you only need to configure the device IP address and port number, and retain the default settings for other parameters.
### Executing Test Cases on Windows ### Executing Test Cases on Windows
#### Building Test Cases #### Building Test Cases
...@@ -720,7 +736,7 @@ Test cases cannot be built on Windows. You need to run the following command to ...@@ -720,7 +736,7 @@ Test cases cannot be built on Windows. You need to run the following command to
``` ```
./build.sh --product-name hispark_taurus_standard --build-target make_test ./build.sh --product-name hispark_taurus_standard --build-target make_test
``` ```
>Note: > **NOTE**<br>
>- **product-name**: specifies the name of the product to build, for example, **hispark_taurus_standard**. >- **product-name**: specifies the name of the product to build, for example, **hispark_taurus_standard**.
>- **build-target**: specifies the test case to build. **make_test** indicates all test cases. You can specify the test cases based on requirements. >- **build-target**: specifies the test case to build. **make_test** indicates all test cases. You can specify the test cases based on requirements.
...@@ -731,7 +747,8 @@ After the build is complete, the test cases are automatically saved in **out/his ...@@ -731,7 +747,8 @@ After the build is complete, the test cases are automatically saved in **out/his
2. Copy **developertest** and **xdevice** from the Linux environment to the **Test** directory on Windows, and copy the test cases to the **testcase** directory. 2. Copy **developertest** and **xdevice** from the Linux environment to the **Test** directory on Windows, and copy the test cases to the **testcase** directory.
>**Note**: Port the test framework and test cases from the Linux environment to the Windows environment for subsequent execution. > **NOTE**<br>
> Port the test framework and test cases from the Linux environment to the Windows environment for subsequent execution.
3. Modify the **user_config.xml** file. 3. Modify the **user_config.xml** file.
``` ```
...@@ -744,7 +761,8 @@ After the build is complete, the test cases are automatically saved in **out/his ...@@ -744,7 +761,8 @@ After the build is complete, the test cases are automatically saved in **out/his
<dir>D:\Test\testcase\tests</dir> <dir>D:\Test\testcase\tests</dir>
</test_cases> </test_cases>
``` ```
>**Note**: `<testcase>` indicates whether to build test cases. `<dir>` indicates the path for searching for test cases. > **NOTE**<br>
> `<testcase>` indicates whether to build test cases. `<dir>` indicates the path for searching for test cases.
#### Executing Test Cases #### Executing Test Cases
1. Start the test framework. 1. Start the test framework.
...@@ -778,13 +796,15 @@ To enable test cases to be executed on a remote Linux server or a Linux VM, map ...@@ -778,13 +796,15 @@ To enable test cases to be executed on a remote Linux server or a Linux VM, map
hdc_std kill hdc_std kill
hdc_std -m -s 0.0.0.0:8710 hdc_std -m -s 0.0.0.0:8710
``` ```
>**Note**: The IP address and port number are default values. > **NOTE**<br>
> The IP address and port number are default values.
2. On the HDC client, run the following command: 2. On the HDC client, run the following command:
``` ```
hdc_std -s xx.xx.xx.xx:8710 list targets hdc_std -s xx.xx.xx.xx:8710 list targets
``` ```
>**Note**: Enter the IP address of the device to test. > **NOTE**<br>
> Enter the IP address of the device to test.
#### Executing Test Cases #### Executing Test Cases
1. Start the test framework. 1. Start the test framework.
...@@ -819,15 +839,16 @@ You can obtain the test result in the following directory: ...@@ -819,15 +839,16 @@ You can obtain the test result in the following directory:
``` ```
test/developertest/reports/xxxx_xx_xx_xx_xx_xx test/developertest/reports/xxxx_xx_xx_xx_xx_xx
``` ```
>**Note**: The folder for test reports is automatically generated. > **NOTE**<br>
> The folder for test reports is automatically generated.
The folder contains the following files: The folder contains the following files:
| Type| Description| | Type | Description |
| ------------ | ------------ | | ------------ | ------------ |
| result/ |Test cases in standard format| | result/ | Test cases in standard format. |
| log/plan_log_xxxx_xx_xx_xx_xx_xx.log | Test case logs| | log/plan_log_xxxx_xx_xx_xx_xx_xx.log | Test case logs. |
| summary_report.html | Test report summary| | summary_report.html | Test report summary. |
| details_report.html | Detailed test report| | details_report.html | Detailed test report. |
### Test Framework Logs ### Test Framework Logs
``` ```
......
...@@ -10,100 +10,49 @@ bytrace supports the following commands: ...@@ -10,100 +10,49 @@ bytrace supports the following commands:
**Table 1** Commands **Table 1** Commands
<a name="table16802195914247"></a> | Option | Description |
<table><thead align="left"><tr id="row14804759142412"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1280465972411"><a name="p1280465972411"></a><a name="p1280465972411"></a>Option</p> | -------- | -------- |
</th> | -h, --help | Views the help text for bytrace. |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p380414595249"><a name="p380414595249"></a><a name="p380414595249"></a>Description</p> | -b&nbsp;_n_, --buffer_size&nbsp;_n_ | Sets the size of the buffer (KB) for storing and reading traces. The default buffer size is 2048 KB. |
</th> | -t&nbsp;_n_, --time&nbsp;_n_ | Sets the bytrace uptime in seconds, which depends on the time required for analysis. |
</tr> | --trace_clock&nbsp;_clock_ | Sets the type of the clock for adding a timestamp to a trace, which can be **boot** (default), **global**, **mono**, **uptime**, or **perf**. |
</thead> | --trace_begin | Starts capturing traces. |
<tbody><tr id="row1714512123414"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1915412133419"><a name="p1915412133419"></a><a name="p1915412133419"></a>-h, --help</p> | --trace_dump | Dumps traces to a specified position (console where you run this command by default). |
</td> | --trace_finish | Stops capturing traces and dumps traces to a specified position (console where you run this command by default). |
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p6156126341"><a name="p6156126341"></a><a name="p6156126341"></a>Views the help text for bytrace.</p> | -l, --list_categories | Lists the bytrace categories supported by the device. |
</td> | --overwrite | Sets the action to take when the buffer is full. If this option is used, the latest traces are discarded; if this option is not used, the earliest traces are discarded (default). |
</tr> | -o&nbsp;_filename_, --output&nbsp;_filename_ | Outputs traces to a specified file. |
<tr id="row13804135982416"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p18051959152410"><a name="p18051959152410"></a><a name="p18051959152410"></a>-b <em id="i35979186184"><a name="i35979186184"></a><a name="i35979186184"></a>n</em>, --buffer_size <em id="i144491624181811"><a name="i144491624181811"></a><a name="i144491624181811"></a>n</em></p> | -z | Compresses a captured trace. |
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p0805165932419"><a name="p0805165932419"></a><a name="p0805165932419"></a>Sets the size of the buffer (KB) for storing and reading traces. The default buffer size is 2048 KB.</p>
</td>
</tr>
<tr id="row580519592245"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p880510591241"><a name="p880510591241"></a><a name="p880510591241"></a>-t <em id="i8668143912203"><a name="i8668143912203"></a><a name="i8668143912203"></a>n</em>, --time <em id="i841433614202"><a name="i841433614202"></a><a name="i841433614202"></a>n</em></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1480517591245"><a name="p1480517591245"></a><a name="p1480517591245"></a>Sets the bytrace uptime in seconds, which depends on the time required for analysis.</p>
</td>
</tr>
<tr id="row4806175913247"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p980655912242"><a name="p980655912242"></a><a name="p980655912242"></a>--trace_clock <em id="i19464452217"><a name="i19464452217"></a><a name="i19464452217"></a>clock</em></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p11806959142416"><a name="p11806959142416"></a><a name="p11806959142416"></a>Sets the type of the clock for adding a timestamp to a trace, which can be <strong id="b13396101413368"><a name="b13396101413368"></a><a name="b13396101413368"></a>boot</strong> (default), <strong id="b14612918183619"><a name="b14612918183619"></a><a name="b14612918183619"></a>global</strong>, <strong id="b045562173610"><a name="b045562173610"></a><a name="b045562173610"></a>mono</strong>, <strong id="b1132132453612"><a name="b1132132453612"></a><a name="b1132132453612"></a>uptime</strong>, or <strong id="b9888326133616"><a name="b9888326133616"></a><a name="b9888326133616"></a>perf</strong>.</p>
</td>
</tr>
<tr id="row1280635917242"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p180715591244"><a name="p180715591244"></a><a name="p180715591244"></a>--trace_begin</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p480795916243"><a name="p480795916243"></a><a name="p480795916243"></a>Starts capturing traces.</p>
</td>
</tr>
<tr id="row1580717599245"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p38073598242"><a name="p38073598242"></a><a name="p38073598242"></a>--trace_dump</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p148077595245"><a name="p148077595245"></a><a name="p148077595245"></a>Dumps traces to a specified position (console where you run this command by default).</p>
</td>
</tr>
<tr id="row180811592242"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p11808165922419"><a name="p11808165922419"></a><a name="p11808165922419"></a>--trace_finish</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p18809559182420"><a name="p18809559182420"></a><a name="p18809559182420"></a>Stops capturing traces and dumps traces to a specified position (console where you run this command by default).</p>
</td>
</tr>
<tr id="row2809185972420"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2080925922418"><a name="p2080925922418"></a><a name="p2080925922418"></a>-l, --list_categories</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p38091159142414"><a name="p38091159142414"></a><a name="p38091159142414"></a>Lists the bytrace categories supported by the device.</p>
</td>
</tr>
<tr id="row1880912598248"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1681014595244"><a name="p1681014595244"></a><a name="p1681014595244"></a>--overwrite</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p12810165914248"><a name="p12810165914248"></a><a name="p12810165914248"></a>Sets the action to take when the buffer is full. If this option is used, the latest traces are discarded; if this option is not used, the earliest traces are discarded (default).</p>
</td>
</tr>
<tr id="row1181015992414"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p168101859152415"><a name="p168101859152415"></a><a name="p168101859152415"></a>-o <em id="i1367232742113"><a name="i1367232742113"></a><a name="i1367232742113"></a>filename</em>, --output <em id="i4305133012219"><a name="i4305133012219"></a><a name="i4305133012219"></a>filename</em></p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p9810559132410"><a name="p9810559132410"></a><a name="p9810559132410"></a>Outputs traces to a specified file.</p>
</td>
</tr>
<tr id="row8810155982415"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p381145912410"><a name="p381145912410"></a><a name="p381145912410"></a>-z</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1281117592249"><a name="p1281117592249"></a><a name="p1281117592249"></a>Compresses a captured trace.</p>
</td>
</tr>
</tbody>
</table>
## Usage Example<a name="section667273201818"></a> ## Usage Example<a name="section667273201818"></a>
The following are some examples of bytrace commands: The following are some examples of bytrace commands:
- Run the following command to query supported labels: - Query supported labels.
``` ```
bytrace -l bytrace -l
``` ```
Alternatively, you can run the following command: Alternatively, run the following command to query the supported bytrace categories:
``` ```
bytrace --list_categories bytrace --list_categories
``` ```
- Run the following command to capture traces whose label is ability, with the buffer size set to 4096 KB and bytrace uptime set to 10s: - Capture traces whose label is ability, with the buffer size set to 4096 KB and bytrace uptime set to 10s.
``` ```
bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace bytrace -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace
``` ```
- Run the following command to set the clock type for traces to **mono**: - Set the clock type for traces to **mono**.
``` ```
bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace bytrace --trace_clock mono -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace
``` ```
- Run the following command to compress the captured trace: - Compress the captured trace.
``` ```
bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace bytrace -z -b 4096 -t 10 --overwrite ability > /data/mytrace.ftrace
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册