mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-12-03 12:53:17 +00:00
update OpenHarmony 2.0 Canary
This commit is contained in:
parent
7e65880a39
commit
2da052f1e2
15
.gitattributes
vendored
Normal file
15
.gitattributes
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.trp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.apk filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.asm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.8svn filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.9svn filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dylib filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.a filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.so filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bin filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dll filter=lfs diff=lfs merge=lfs -text
|
90
BUILD.gn
Executable file
90
BUILD.gn
Executable file
@ -0,0 +1,90 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/ohos.gni")
|
||||||
|
|
||||||
|
config("appspawn_config") {
|
||||||
|
visibility = [ ":*" ]
|
||||||
|
include_dirs = [
|
||||||
|
"include",
|
||||||
|
"//utils/native/base/include",
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/appexecfwk_core/include/appmgr",
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/appexecfwk_core/include/bundlemgr",
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/appexecfwk_base/include",
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/libeventhandler/include",
|
||||||
|
"${appexecfwk_path}/kits/appkit/native/app/include",
|
||||||
|
"${appexecfwk_path}/common/log/include",
|
||||||
|
"${aafwk_path}/interfaces/innerkits/want/include/ohos/aafwk/content",
|
||||||
|
"${aafwk_path}/interfaces/innerkits/want/include",
|
||||||
|
"${aafwk_path}/interfaces/innerkits/ability_manager/include",
|
||||||
|
"${aafwk_path}/interfaces/innerkits/base/include",
|
||||||
|
"${aafwk_path}/frameworks/kits/ability/native/include",
|
||||||
|
"${aafwk_path}/services/abilitymgr/include",
|
||||||
|
"${distributedschedule_path}/services/dtbschedmgr/include",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_executable("appspawn") {
|
||||||
|
sources = [ "${appspawn_path}/src/main.cpp" ]
|
||||||
|
configs = [ ":appspawn_config" ]
|
||||||
|
deps = [ "${appspawn_path}:appspawn_server" ]
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
|
||||||
|
install_enable = true
|
||||||
|
subsystem_name = "${subsystem_name}"
|
||||||
|
part_name = "${part_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_shared_library("appspawn_server") {
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/appspawn_msg_peer.cpp",
|
||||||
|
"${appspawn_path}/src/appspawn_server.cpp",
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/server_socket.cpp",
|
||||||
|
]
|
||||||
|
configs = [ ":appspawn_config" ]
|
||||||
|
ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ]
|
||||||
|
deps = [
|
||||||
|
"${aafwk_path}/frameworks/kits/ability/native:abilitykit_native",
|
||||||
|
"${appexecfwk_path}/kits:appkit_native",
|
||||||
|
"//utils/native/base:utils",
|
||||||
|
]
|
||||||
|
external_deps = [
|
||||||
|
"hiviewdfx_hilog_native:libhilog",
|
||||||
|
"ipc:ipc_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
subsystem_name = "${subsystem_name}"
|
||||||
|
part_name = "${part_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_shared_library("appspawn_socket_client") {
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/client_socket.cpp",
|
||||||
|
]
|
||||||
|
configs = [ ":appspawn_config" ]
|
||||||
|
deps = [ "//utils/native/base:utils" ]
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
|
||||||
|
subsystem_name = "${subsystem_name}"
|
||||||
|
part_name = "${part_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_prebuilt_etc("appspawn.rc") {
|
||||||
|
source = "appspawn.rc"
|
||||||
|
relative_install_dir = "init"
|
||||||
|
subsystem_name = "${subsystem_name}"
|
||||||
|
part_name = "${part_name}"
|
||||||
|
}
|
177
LICENSE
Normal file
177
LICENSE
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
70
OAT.xml
Normal file
70
OAT.xml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- 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.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This is project config file for OpenHarmony OSS Audit Tool, if you have any questions or concerns, please email chenyaxun@huawei.com.
|
||||||
|
-->
|
||||||
|
<!-- OAT(OSS Audit Tool) configuration guide:
|
||||||
|
basedir: Root dir, the basedir + project path is the real source file location.
|
||||||
|
licensefile:
|
||||||
|
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
|
||||||
|
|
||||||
|
tasklist(only for batch mode):
|
||||||
|
1. task: Define oat check thread, each task will start a new thread.
|
||||||
|
2. task name: Only an name, no practical effect.
|
||||||
|
3. task policy: Default policy for projects under this task, this field is required and the specified policy must defined in policylist.
|
||||||
|
4. task filter: Default filefilter for projects under this task, this field is required and the specified filefilter must defined in filefilterlist.
|
||||||
|
5. task project: Projects to be checked, the path field define the source root dir of the project.
|
||||||
|
|
||||||
|
|
||||||
|
policyList:
|
||||||
|
1. policy: All policyitems will be merged to default OAT.xml rules, the name of policy doesn't affect OAT check process.
|
||||||
|
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
|
||||||
|
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||||
|
3. policyitem type:
|
||||||
|
"compatibility" is used to check license compatibility in the specified path;
|
||||||
|
"license" is used to check source license header in the specified path;
|
||||||
|
"copyright" is used to check source copyright header in the specified path;
|
||||||
|
"import" is used to check source dependency in the specified path, such as import ... ,include ...
|
||||||
|
"filetype" is used to check file type in the specified path, supported file types: archive, binary
|
||||||
|
"filename" is used to check whether the specified file exists in the specified path(support projectroot in default OAT.xml), supported file names: LICENSE, README, README.OpenSource
|
||||||
|
|
||||||
|
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
|
||||||
|
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
|
||||||
|
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
|
||||||
|
7. policyitem filefilter: Used to bind filefilter which define filter rules.
|
||||||
|
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
|
||||||
|
|
||||||
|
Note:If the text contains special characters, please escape them according to the following rules:
|
||||||
|
" == >
|
||||||
|
& == >
|
||||||
|
' == >
|
||||||
|
< == >
|
||||||
|
> == >
|
||||||
|
-->
|
||||||
|
<configuration>
|
||||||
|
<oatconfig>
|
||||||
|
<licensefile></licensefile>
|
||||||
|
<policylist>
|
||||||
|
<policy name="projectPolicy" desc="">
|
||||||
|
</policy>
|
||||||
|
</policylist>
|
||||||
|
<filefilterlist>
|
||||||
|
<filefilter name="defaultFilter" desc="Files not to check">
|
||||||
|
<filteritem type="filename" name="*.hap|*.rpk" desc="valid and invalid bundle files for tests"/>
|
||||||
|
</filefilter>
|
||||||
|
</filefilterlist>
|
||||||
|
</oatconfig>
|
||||||
|
</configuration>
|
36
README.en.md
36
README.en.md
@ -1,36 +0,0 @@
|
|||||||
# startup_appspawn
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
Appspawn module for spawning application processes | 应用孵化模块
|
|
||||||
|
|
||||||
#### Software Architecture
|
|
||||||
Software architecture description
|
|
||||||
|
|
||||||
#### Installation
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Instructions
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Contribution
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create Feat_xxx branch
|
|
||||||
3. Commit your code
|
|
||||||
4. Create Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### Gitee Feature
|
|
||||||
|
|
||||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
|
||||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
|
||||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
37
README.md
37
README.md
@ -1,37 +0,0 @@
|
|||||||
# startup_appspawn
|
|
||||||
|
|
||||||
#### 介绍
|
|
||||||
Appspawn module for spawning application processes | 应用孵化模块
|
|
||||||
|
|
||||||
#### 软件架构
|
|
||||||
软件架构说明
|
|
||||||
|
|
||||||
|
|
||||||
#### 安装教程
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### 使用说明
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### 参与贡献
|
|
||||||
|
|
||||||
1. Fork 本仓库
|
|
||||||
2. 新建 Feat_xxx 分支
|
|
||||||
3. 提交代码
|
|
||||||
4. 新建 Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### 特技
|
|
||||||
|
|
||||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
|
||||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
|
||||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
31
README_zh.md
Executable file
31
README_zh.md
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
# appspawn应用孵化器组件
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
应用孵化器,负责接受应用程序框架的命令孵化应用进程,设置其对应权限,并调用应用程序框架的入口。
|
||||||
|
|
||||||
|
其主要的结构及流程如下图所示:
|
||||||
|
|
||||||
|
![](figures/appspawn.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
```
|
||||||
|
base/startup/appspawn_standard
|
||||||
|
├── include # 应用孵化器组件头文件
|
||||||
|
├── parameter # 应用孵化器组件系统参数
|
||||||
|
├── src # 应用孵化器组件源文件
|
||||||
|
└── test # 应用孵化器组件测试代码
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 相关仓
|
||||||
|
|
||||||
|
appspawn应用孵化器组件
|
||||||
|
|
||||||
|
**startup_appspawn**
|
||||||
|
|
21
appspawn.gni
Normal file
21
appspawn.gni
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
appspawn_path = "//base/startup/appspawn_standard"
|
||||||
|
appexecfwk_path = "//foundation/appexecfwk/standard"
|
||||||
|
aafwk_path = "//foundation/aafwk/standard"
|
||||||
|
communication_path = "//foundation/communication/ipc"
|
||||||
|
distributedschedule_path = "//foundation/distributedschedule/dmsfwk"
|
||||||
|
subsystem_name = "startup"
|
||||||
|
part_name = "startup_l2"
|
||||||
|
module_output_path = "${part_name}/appspawn_l2"
|
22
appspawn.rc
Normal file
22
appspawn.rc
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
on late-fs
|
||||||
|
start appspawn
|
||||||
|
|
||||||
|
service appspawn /system/bin/appspawn
|
||||||
|
class appspawn
|
||||||
|
priority -20
|
||||||
|
user root
|
||||||
|
group root
|
||||||
|
seclabel u:r:appspawn:s0
|
BIN
figures/appspawn.png
Executable file
BIN
figures/appspawn.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
79
include/appspawn_msg_peer.h
Normal file
79
include/appspawn_msg_peer.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APPSPAWN_MSG_PEER_H
|
||||||
|
#define APPSPAWN_MSG_PEER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "client_socket.h"
|
||||||
|
#include "server_socket.h"
|
||||||
|
#include "nocopyable.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
class AppSpawnMsgPeer {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor used to delete the default constructor.
|
||||||
|
*/
|
||||||
|
AppSpawnMsgPeer() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used to create a AppSpawnMsgPeer.
|
||||||
|
*/
|
||||||
|
AppSpawnMsgPeer(const std::shared_ptr<ServerSocket> &socket, int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor used to destory a AppSpawnMsgPeer
|
||||||
|
*/
|
||||||
|
~AppSpawnMsgPeer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables copy and moving of AppSpawnMsgPeer.
|
||||||
|
*/
|
||||||
|
DISALLOW_COPY_AND_MOVE(AppSpawnMsgPeer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the message about the app property.
|
||||||
|
*/
|
||||||
|
ClientSocket::AppProperty *GetMsg() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the PID of the application process in the response sent to the AMS service after AppSpawn forks the
|
||||||
|
* application process.
|
||||||
|
*
|
||||||
|
* @param pid Indicates the PID of the application process.
|
||||||
|
*/
|
||||||
|
int Response(pid_t pid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the message from MsgPeer over the socket.
|
||||||
|
*/
|
||||||
|
int MsgPeer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the connection file description used by the AMS service to connect to AppSpawn.
|
||||||
|
*/
|
||||||
|
int GetConnectFd() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int connectFd_ = -1;
|
||||||
|
std::shared_ptr<ServerSocket> socket_ = nullptr;
|
||||||
|
std::unique_ptr<int8_t[]> buf_ = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
||||||
|
#endif
|
139
include/appspawn_server.h
Normal file
139
include/appspawn_server.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APPSPAWN_SERVER_H
|
||||||
|
#define APPSPAWN_SERVER_H
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "appspawn_msg_peer.h"
|
||||||
|
#include "server_socket.h"
|
||||||
|
#include "nocopyable.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
|
||||||
|
class AppSpawnServer {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor used to delete the default constructor.
|
||||||
|
*/
|
||||||
|
AppSpawnServer() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used to create a AppSpawnServer.
|
||||||
|
*/
|
||||||
|
explicit AppSpawnServer(const std::string &socketName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor used to destory a AppSpawnServer
|
||||||
|
*/
|
||||||
|
~AppSpawnServer() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables copying and moving for the AppSpawnServer.
|
||||||
|
*/
|
||||||
|
DISALLOW_COPY_AND_MOVE(AppSpawnServer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the AppSpawn core function for the server to receive messages from AMS service.
|
||||||
|
*
|
||||||
|
* @param longProcName Indicates the long process name.
|
||||||
|
* @param longProcNameLen Indicates the length of long process name.
|
||||||
|
*/
|
||||||
|
bool ServerMain(char *longProcName, int64_t longProcNameLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the server listening socket.
|
||||||
|
*
|
||||||
|
* @param isRunning Indicates whether the server is running. Value false means to stop the server and exit.
|
||||||
|
*/
|
||||||
|
void SetRunning(bool isRunning);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set its value to the member variable socket_.
|
||||||
|
*
|
||||||
|
* @param serverSocket Indicates the server socket.
|
||||||
|
*/
|
||||||
|
void SetServerSocket(const std::shared_ptr<ServerSocket> &serverSocket);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr uint8_t BITLEN32 = 32;
|
||||||
|
static constexpr uint8_t FDLEN2 = 2;
|
||||||
|
static constexpr uint8_t FD_INIT_VALUE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the MsgPeer method in the AppSpawnMsgPeer class to read message from socket, and notify the ServerMain to
|
||||||
|
* unlock.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connect FDs.
|
||||||
|
*/
|
||||||
|
void MsgPeer(int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the connect fd and creates a thread to receive messages.
|
||||||
|
*/
|
||||||
|
void ConnectionPeer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a name for an applicaiton process.
|
||||||
|
*
|
||||||
|
* @param longProcName Indicates the length of long process name.
|
||||||
|
* @param longProcNameLen Indicates the long process name.
|
||||||
|
* @param processName Indicates the process name from the AMS service.
|
||||||
|
* @param len Indicates the size of processName.
|
||||||
|
*/
|
||||||
|
int32_t SetProcessName(char *longProcName, int64_t longProcNameLen, const char *processName, int32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the uid and gid of an application process.
|
||||||
|
*
|
||||||
|
* @param uid Indicates the uid of the application process.
|
||||||
|
* @param gid Indicates the gid of the application process.
|
||||||
|
* @param gidTable Indicates an array of application processes.
|
||||||
|
* @param gidCount Indicates the number of GIDs.
|
||||||
|
*/
|
||||||
|
int32_t SetUidGid(const uint32_t uid, const uint32_t gid, const uint32_t *gidTable, const uint32_t gidCount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets FDs in an application process.
|
||||||
|
*/
|
||||||
|
int32_t SetFileDescriptors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets capabilities of an application process.
|
||||||
|
*/
|
||||||
|
int32_t SetCapabilities();
|
||||||
|
|
||||||
|
bool SetAppProcProperty(int connectFd, const ClientSocket::AppProperty *appProperty, char *longProcName,
|
||||||
|
int64_t longProcNameLen, const int32_t fd[FDLEN2]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string deviceNull_ = "/dev/null";
|
||||||
|
std::string socketName_{};
|
||||||
|
std::shared_ptr<ServerSocket> socket_ = nullptr;
|
||||||
|
std::mutex mut_{};
|
||||||
|
mutable std::condition_variable dataCond_{};
|
||||||
|
std::queue<std::unique_ptr<AppSpawnMsgPeer>> appQueue_{};
|
||||||
|
std::function<int(const ClientSocket::AppProperty &)> propertyHandler_ = nullptr;
|
||||||
|
std::function<void(const std::string &)> errHandlerHook_ = nullptr;
|
||||||
|
bool isRunning_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
||||||
|
|
||||||
|
#endif
|
111
include/appspawn_socket.h
Normal file
111
include/appspawn_socket.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APPSPAWN_SOCKET_H
|
||||||
|
#define APPSPAWN_SOCKET_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nocopyable.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
class AppSpawnSocket {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor used to delete the default constructor.
|
||||||
|
*/
|
||||||
|
AppSpawnSocket() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used to create a AppSpawnSocket.
|
||||||
|
*/
|
||||||
|
explicit AppSpawnSocket(const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor used to destory a AppSpawnSocket
|
||||||
|
*/
|
||||||
|
virtual ~AppSpawnSocket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables copying and moving for the AppSpawnSocket.
|
||||||
|
*/
|
||||||
|
DISALLOW_COPY_AND_MOVE(AppSpawnSocket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the socket's file descriptor (FD).
|
||||||
|
*/
|
||||||
|
int GetSocketFd() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads messages from the AppSpawn socket.
|
||||||
|
*
|
||||||
|
* @param socketFd Indicates the socket's FD.
|
||||||
|
* @param buf Indicates the message buffer.
|
||||||
|
* @param len Indicates the message size.
|
||||||
|
*
|
||||||
|
* @return -1:failed;other means message size.
|
||||||
|
*/
|
||||||
|
virtual int ReadSocketMessage(int socketFd, void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes messages to the AppSpawn socket.
|
||||||
|
*
|
||||||
|
* @param socketFd Indicates the socket's FD.
|
||||||
|
* @param buf Indicates the message buffer.
|
||||||
|
* @param len Indicates the message size.
|
||||||
|
*
|
||||||
|
* @return -1:failed;other means message size.
|
||||||
|
*/
|
||||||
|
virtual int WriteSocketMessage(int socketFd, const void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes an AppSpawn socket.
|
||||||
|
*
|
||||||
|
* @param socketFd Indicates the socket's FD.
|
||||||
|
*/
|
||||||
|
static void CloseSocket(int &socketFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AppSpawn socket.
|
||||||
|
*
|
||||||
|
* @return -1:failed;other means connection FD.
|
||||||
|
*/
|
||||||
|
static int CreateSocket();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Sets the socket name to the socket address.
|
||||||
|
*
|
||||||
|
* @return -1:failed; 0:success
|
||||||
|
*/
|
||||||
|
int PackSocketAddr();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int socketFd_ = -1;
|
||||||
|
std::string socketName_{};
|
||||||
|
struct sockaddr_un socketAddr_ {};
|
||||||
|
socklen_t socketAddrLen_ = 0;
|
||||||
|
const std::string socketDir_ = "/dev/socket/";
|
||||||
|
const unsigned int listenBacklog_ = 50; // 50: max num of clients
|
||||||
|
static constexpr struct timeval SOCKET_TIMEOUT = {5, 0}; // 5, 0: { 5 sec, 0 msec } for timeout
|
||||||
|
};
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
||||||
|
#endif
|
110
include/client_socket.h
Normal file
110
include/client_socket.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APPSPAWN_SOCKET_CLIENT_H
|
||||||
|
#define APPSPAWN_SOCKET_CLIENT_H
|
||||||
|
|
||||||
|
#include "appspawn_socket.h"
|
||||||
|
#include "nocopyable.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
class ClientSocket : public AppSpawnSocket {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor used to create a ClientSocket
|
||||||
|
*/
|
||||||
|
explicit ClientSocket(const std::string &client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor used to destory a ClientSocket
|
||||||
|
*/
|
||||||
|
virtual ~ClientSocket() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables copying and moving for the ClientSocket.
|
||||||
|
*/
|
||||||
|
DISALLOW_COPY_AND_MOVE(ClientSocket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a local client socket.
|
||||||
|
*/
|
||||||
|
virtual int CreateClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a client socket.
|
||||||
|
*/
|
||||||
|
virtual void CloseClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a client socket.
|
||||||
|
*/
|
||||||
|
virtual int ConnectSocket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes messages to a client socket.
|
||||||
|
*
|
||||||
|
* @param buf Indicates the pointer to the message buffer.
|
||||||
|
* @param len Indicates the message length.
|
||||||
|
*/
|
||||||
|
virtual int WriteSocketMessage(const void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads messages from a client socket.
|
||||||
|
*
|
||||||
|
* @param buf Indicates the pointer to the message buffer.
|
||||||
|
* @param len Indicates the message length.
|
||||||
|
*/
|
||||||
|
virtual int ReadSocketMessage(void *buf, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses functions of the parent class.
|
||||||
|
*/
|
||||||
|
using AppSpawnSocket::CloseSocket;
|
||||||
|
using AppSpawnSocket::CreateSocket;
|
||||||
|
using AppSpawnSocket::GetSocketFd;
|
||||||
|
using AppSpawnSocket::ReadSocketMessage;
|
||||||
|
using AppSpawnSocket::WriteSocketMessage;
|
||||||
|
|
||||||
|
enum AppType {
|
||||||
|
APP_TYPE_DEFAULT = 0, // JavaScript app
|
||||||
|
APP_TYPE_NATIVE // Native C++ app
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr int APPSPAWN_MSG_MAX_SIZE = 4096; // appspawn message max size
|
||||||
|
static constexpr int LEN_PROC_NAME = 256; // process name length
|
||||||
|
static constexpr int LEN_SO_PATH = 256; // load so lib
|
||||||
|
static constexpr int MAX_GIDS = 64;
|
||||||
|
|
||||||
|
struct AppProperty {
|
||||||
|
uint32_t uid; // the UNIX uid that the child process setuid() to after fork()
|
||||||
|
uint32_t gid; // the UNIX gid that the child process setgid() to after fork()
|
||||||
|
uint32_t gidTable[MAX_GIDS]; // a list of UNIX gids that the child process setgroups() to after fork()
|
||||||
|
uint32_t gidCount; // the size of gidTable
|
||||||
|
char processName[LEN_PROC_NAME]; // process name
|
||||||
|
char soPath[LEN_SO_PATH]; // so lib path
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Connects a client socket.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's FD.
|
||||||
|
*/
|
||||||
|
int ConnectSocket(int connectFd);
|
||||||
|
};
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
||||||
|
#endif
|
132
include/server_socket.h
Normal file
132
include/server_socket.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APPSPAWN_SOCKET_SERVER_H
|
||||||
|
#define APPSPAWN_SOCKET_SERVER_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "appspawn_socket.h"
|
||||||
|
#include "nocopyable.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
class ServerSocket : public AppSpawnSocket {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor used to create a ServerSocket
|
||||||
|
*/
|
||||||
|
explicit ServerSocket(const std::string &server);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor used to destory a ServerSocket
|
||||||
|
*/
|
||||||
|
virtual ~ServerSocket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables copying and moving for ServerSocket.
|
||||||
|
*/
|
||||||
|
DISALLOW_COPY_AND_MOVE(ServerSocket);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a socket connection.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's file descriptor (FD).
|
||||||
|
*/
|
||||||
|
virtual void CloseConnection(int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the connection's FD.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's file descriptor (FD).
|
||||||
|
*/
|
||||||
|
virtual void SaveConnection(int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a server socket.
|
||||||
|
*/
|
||||||
|
virtual void CloseServer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the server monitor.
|
||||||
|
*/
|
||||||
|
virtual void CloseServerMonitor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates server socket, binds socket and listens it.
|
||||||
|
*
|
||||||
|
* @return -1:failed; 0:success
|
||||||
|
*/
|
||||||
|
virtual int RegisterServerSocket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets socket option and waits for connection.
|
||||||
|
*
|
||||||
|
* @return -1:failed;other means connection FD.
|
||||||
|
*/
|
||||||
|
virtual int WaitForConnection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the connection's FD.
|
||||||
|
*
|
||||||
|
* @return -1:failed; 0:success
|
||||||
|
*/
|
||||||
|
virtual int VerifyConnection(int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses functions of the parent class.
|
||||||
|
*/
|
||||||
|
using AppSpawnSocket::CloseSocket;
|
||||||
|
using AppSpawnSocket::CreateSocket;
|
||||||
|
using AppSpawnSocket::GetSocketFd;
|
||||||
|
using AppSpawnSocket::ReadSocketMessage;
|
||||||
|
using AppSpawnSocket::WriteSocketMessage;
|
||||||
|
|
||||||
|
static constexpr uid_t AID_ROOT = 0; // chown owner
|
||||||
|
static constexpr gid_t AID_SYSTEM = 1000; // chown group
|
||||||
|
static constexpr mode_t SOCKET_PERM = 0660; // root system can read and write appspawn socket
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Binds a socket and sets socket attributes.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's FD.
|
||||||
|
*/
|
||||||
|
int BindSocket(int connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a socket and binds it.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's FD.
|
||||||
|
*/
|
||||||
|
int RegisterServerSocket(int &connectFd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts a socket.
|
||||||
|
*
|
||||||
|
* @param connectFd Indicates the connection's FD.
|
||||||
|
*/
|
||||||
|
int WaitForConnection(int connectFd);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<int> connectFds_ = {};
|
||||||
|
std::mutex mutexConnect_;
|
||||||
|
};
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
||||||
|
#endif
|
30
ohos.build
Normal file
30
ohos.build
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"subsystem": "startup",
|
||||||
|
"parts": {
|
||||||
|
"startup_l2": {
|
||||||
|
"module_list": [
|
||||||
|
"//base/startup/appspawn_standard:appspawn",
|
||||||
|
"//base/startup/appspawn_standard:appspawn_server",
|
||||||
|
"//base/startup/appspawn_standard:appspawn_socket_client",
|
||||||
|
"//base/startup/appspawn_standard:appspawn.rc",
|
||||||
|
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
|
||||||
|
"//base/startup/syspara_lite/interfaces/kits/js:deviceinfo",
|
||||||
|
"//base/startup/syspara_lite/interfaces/kits/js:systemparameter"
|
||||||
|
],
|
||||||
|
"inner_kits": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"header_files": [
|
||||||
|
"parameter.h"
|
||||||
|
],
|
||||||
|
"header_base": "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include/"
|
||||||
|
},
|
||||||
|
"name": "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"test_list": [
|
||||||
|
"//base/startup/appspawn_standard/test:moduletest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
96
src/appspawn_msg_peer.cpp
Normal file
96
src/appspawn_msg_peer.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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 "appspawn_msg_peer.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnMain"};
|
||||||
|
|
||||||
|
AppSpawnMsgPeer::AppSpawnMsgPeer(const std::shared_ptr<ServerSocket> &socket, int connectFd)
|
||||||
|
: connectFd_(connectFd), socket_(socket)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AppSpawnMsgPeer::~AppSpawnMsgPeer()
|
||||||
|
{
|
||||||
|
if ((socket_ != nullptr) && (connectFd_ >= 0)) {
|
||||||
|
socket_->CloseConnection(connectFd_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSocket::AppProperty *AppSpawnMsgPeer::GetMsg() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<ClientSocket::AppProperty *>(buf_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::GetConnectFd() const
|
||||||
|
{
|
||||||
|
return connectFd_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::Response(pid_t pid)
|
||||||
|
{
|
||||||
|
if ((socket_ == nullptr) || (connectFd_ < 0)) {
|
||||||
|
HiLog::Error(LABEL, "Invalid socket params: connectFd %d", connectFd_);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket_->WriteSocketMessage(connectFd_, &pid, sizeof(pid)) != sizeof(pid)) {
|
||||||
|
HiLog::Error(LABEL, "Failed to write message: connectFd %d", connectFd_);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::MsgPeer()
|
||||||
|
{
|
||||||
|
if ((socket_ == nullptr) || (connectFd_ < 0)) {
|
||||||
|
HiLog::Error(LABEL, "Failed to init socket: connectFd %{public}d", connectFd_);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t msgLen = sizeof(ClientSocket::AppProperty);
|
||||||
|
buf_ = std::make_unique<int8_t[]>(msgLen);
|
||||||
|
if (buf_ == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "buf_ is null pointer!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t rLen = 0;
|
||||||
|
|
||||||
|
for (int8_t *offset = buf_.get(); msgLen > 0; offset += rLen, msgLen -= rLen) {
|
||||||
|
rLen = socket_->ReadSocketMessage(connectFd_, offset, msgLen);
|
||||||
|
if (rLen == 0) {
|
||||||
|
HiLog::Info(LABEL, "AppSpawnMsgPeer::MsgPeer ReadSocketMessage function value is 0.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rLen < 0) || (rLen > msgLen)) {
|
||||||
|
HiLog::Error(LABEL, "AppSpawnMsgPeer::Failed to read msg from socket %{public}d", connectFd_);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
453
src/appspawn_server.cpp
Normal file
453
src/appspawn_server.cpp
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
/*
|
||||||
|
* 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 "appspawn_server.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <sys/capability.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "main_thread.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
#define GRAPHIC_PERMISSION_CHECK
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr int32_t ERR_PIPE_FAIL = -100;
|
||||||
|
constexpr int32_t MAX_LEN_SHORT_NAME = 16;
|
||||||
|
constexpr int32_t WAIT_DELAY_US = 100 * 1000; // 100ms
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnServer"};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void SignalHandler(int) /* signal_number */
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||||
|
if (WIFEXITED(status) && WEXITSTATUS(status)) {
|
||||||
|
HiLog::Info(LABEL, "Process %{public}d exited cleanly %{public}d", pid, WEXITSTATUS(status));
|
||||||
|
} else if (WIFSIGNALED(status)) {
|
||||||
|
if (WTERMSIG(status) != SIGKILL) {
|
||||||
|
HiLog::Info(LABEL, "Process %{public}d exited due to signal %{public}d", pid, WTERMSIG(status));
|
||||||
|
}
|
||||||
|
if (WCOREDUMP(status)) {
|
||||||
|
HiLog::Info(LABEL, "Process %{public}d dumped core.", pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InstallSigHandler()
|
||||||
|
{
|
||||||
|
struct sigaction sa = {};
|
||||||
|
sa.sa_handler = SignalHandler;
|
||||||
|
int err = sigaction(SIGCHLD, &sa, nullptr);
|
||||||
|
if (err < 0) {
|
||||||
|
HiLog::Error(LABEL, "Error installing SIGCHLD handler: %{public}s", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigaction sah = {};
|
||||||
|
sah.sa_handler = SIG_IGN;
|
||||||
|
err = sigaction(SIGHUP, &sah, nullptr);
|
||||||
|
if (err < 0) {
|
||||||
|
HiLog::Error(LABEL, "Error installing SIGHUP handler: %{public}s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UninstallSigHandler()
|
||||||
|
{
|
||||||
|
struct sigaction sa = {};
|
||||||
|
sa.sa_handler = SIG_DFL;
|
||||||
|
int err = sigaction(SIGCHLD, &sa, nullptr);
|
||||||
|
if (err < 0) {
|
||||||
|
HiLog::Error(LABEL, "Error uninstalling SIGCHLD handler: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigaction sah = {};
|
||||||
|
sah.sa_handler = SIG_DFL;
|
||||||
|
err = sigaction(SIGHUP, &sah, nullptr);
|
||||||
|
if (err < 0) {
|
||||||
|
HiLog::Error(LABEL, "Error uninstalling SIGHUP handler: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AppSpawnServer::AppSpawnServer(const std::string &socketName)
|
||||||
|
{
|
||||||
|
socketName_ = socketName;
|
||||||
|
socket_ = std::make_shared<ServerSocket>(socketName_);
|
||||||
|
isRunning_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServer::MsgPeer(int connectFd)
|
||||||
|
{
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> msgPeer = std::make_unique<AppSpawnMsgPeer>(socket_, connectFd);
|
||||||
|
if (msgPeer == nullptr || msgPeer->MsgPeer() != 0) {
|
||||||
|
HiLog::Error(LABEL, "Failed to listen connection %d, %s", connectFd, strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(mut_);
|
||||||
|
appQueue_.push(std::move(msgPeer));
|
||||||
|
dataCond_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServer::ConnectionPeer()
|
||||||
|
{
|
||||||
|
int connectFd;
|
||||||
|
|
||||||
|
/* AppSpawn keeps receiving msg from AppMgr and never exits */
|
||||||
|
while (isRunning_) {
|
||||||
|
connectFd = socket_->WaitForConnection();
|
||||||
|
if (connectFd < 0) {
|
||||||
|
usleep(WAIT_DELAY_US);
|
||||||
|
HiLog::Info(LABEL, "AppSpawnServer::ConnectionPeer connectFd is %{public}d", connectFd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mut_.lock(); // Ensure that mutex in SaveConnection is unlocked before being forked
|
||||||
|
socket_->SaveConnection(connectFd);
|
||||||
|
mut_.unlock();
|
||||||
|
std::thread(&AppSpawnServer::MsgPeer, this, connectFd).detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppSpawnServer::ServerMain(char *longProcName, int64_t longProcNameLen)
|
||||||
|
{
|
||||||
|
if (socket_->RegisterServerSocket() != 0) {
|
||||||
|
HiLog::Error(LABEL, "AppSpawnServer::Failed to register server socket");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread(&AppSpawnServer::ConnectionPeer, this).detach();
|
||||||
|
|
||||||
|
while (isRunning_) {
|
||||||
|
std::unique_lock<std::mutex> lock(mut_);
|
||||||
|
dataCond_.wait(lock, [this] { return !this->appQueue_.empty(); });
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> msg = std::move(appQueue_.front());
|
||||||
|
appQueue_.pop();
|
||||||
|
int connectFd = msg->GetConnectFd();
|
||||||
|
ClientSocket::AppProperty *appProperty = msg->GetMsg();
|
||||||
|
|
||||||
|
// check appProperty
|
||||||
|
if (appProperty == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "appProperty is nullptr");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appProperty->gidCount > ClientSocket::MAX_GIDS) {
|
||||||
|
HiLog::Error(LABEL, "gidCount error: %{public}u", appProperty->gidCount);
|
||||||
|
msg->Response(-EINVAL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(appProperty->processName) == 0) {
|
||||||
|
HiLog::Error(LABEL, "process name length is 0");
|
||||||
|
msg->Response(-EINVAL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallSigHandler();
|
||||||
|
|
||||||
|
int32_t fd[FDLEN2] = {FD_INIT_VALUE, FD_INIT_VALUE};
|
||||||
|
int32_t buff = 0;
|
||||||
|
if (pipe(fd) == -1) {
|
||||||
|
HiLog::Error(LABEL, "create pipe fail");
|
||||||
|
msg->Response(ERR_PIPE_FAIL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
HiLog::Error(LABEL, "AppSpawnServer::Failed to fork new process, errno = %{public}d", errno);
|
||||||
|
// close pipe fds
|
||||||
|
close(fd[0]);
|
||||||
|
close(fd[1]);
|
||||||
|
msg->Response(-errno);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
return SetAppProcProperty(connectFd, appProperty, longProcName, longProcNameLen, fd);
|
||||||
|
}
|
||||||
|
// parent process
|
||||||
|
// close write end
|
||||||
|
close(fd[1]);
|
||||||
|
// wait child process result
|
||||||
|
read(fd[0], &buff, sizeof(buff));
|
||||||
|
// close read end
|
||||||
|
close(fd[0]);
|
||||||
|
|
||||||
|
HiLog::Info(LABEL, "child process init %{public}s", (buff == ERR_OK) ? "success" : "fail");
|
||||||
|
|
||||||
|
if (buff == ERR_OK) {
|
||||||
|
// send pid to AppManagerService
|
||||||
|
msg->Response(pid);
|
||||||
|
} else {
|
||||||
|
// send error code to AppManagerService
|
||||||
|
msg->Response(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
// close socket connection
|
||||||
|
socket_->CloseConnection(connectFd);
|
||||||
|
HiLog::Debug(LABEL, "AppSpawnServer::parent process create app finish, pid = %{public}d", pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AppSpawnServer::SetProcessName(
|
||||||
|
char *longProcName, int64_t longProcNameLen, const char *processName, int32_t len)
|
||||||
|
{
|
||||||
|
if (longProcName == nullptr || processName == nullptr || len <= 0) {
|
||||||
|
HiLog::Error(LABEL, "process name is nullptr or length error");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char shortName[MAX_LEN_SHORT_NAME];
|
||||||
|
if (memset_s(shortName, sizeof(shortName), 0, sizeof(shortName)) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "Failed to memset short name");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process short name max length 16 bytes.
|
||||||
|
if (len > MAX_LEN_SHORT_NAME) {
|
||||||
|
if (strncpy_s(shortName, MAX_LEN_SHORT_NAME, processName, MAX_LEN_SHORT_NAME - 1) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "strncpy_s short name error: %{public}s", strerror(errno));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strncpy_s(shortName, MAX_LEN_SHORT_NAME, processName, len) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "strncpy_s short name error: %{public}s", strerror(errno));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set short name
|
||||||
|
if (prctl(PR_SET_NAME, shortName) == -1) {
|
||||||
|
HiLog::Error(LABEL, "prctl(PR_SET_NAME) error: %{public}s", strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset longProcName
|
||||||
|
if (memset_s(longProcName, longProcNameLen, 0, longProcNameLen) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "Failed to memset long process name");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set long process name
|
||||||
|
if (strncpy_s(longProcName, len, processName, len) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "strncpy_s long name error: %{public}s", strerror(errno));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AppSpawnServer::SetUidGid(
|
||||||
|
const uint32_t uid, const uint32_t gid, const uint32_t *gitTable, const uint32_t gidCount)
|
||||||
|
{
|
||||||
|
// set gids
|
||||||
|
if (setgroups(gidCount, reinterpret_cast<const gid_t *>(&gitTable[0])) == -1) {
|
||||||
|
HiLog::Error(LABEL, "setgroups failed: %{public}s, gids.size=%{public}u", strerror(errno), gidCount);
|
||||||
|
return (-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set gid
|
||||||
|
if (setresgid(gid, gid, gid) == -1) {
|
||||||
|
HiLog::Error(LABEL, "setgid(%{public}u) failed: %{public}s", gid, strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the effective user ID is changed from 0 to nonzero, then all capabilities are cleared from the effective set
|
||||||
|
if (setresuid(uid, uid, uid) == -1) {
|
||||||
|
HiLog::Error(LABEL, "setuid(%{public}u) failed: %{public}s", uid, strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
}
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AppSpawnServer::SetFileDescriptors()
|
||||||
|
{
|
||||||
|
// close stdin stdout stderr
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
|
|
||||||
|
// redirect to /dev/null
|
||||||
|
int dev_null_fd = open(deviceNull_.c_str(), O_RDWR);
|
||||||
|
if (dev_null_fd == -1) {
|
||||||
|
HiLog::Error(LABEL, "open dev_null error: %{public}s", strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stdin
|
||||||
|
if (dup2(dev_null_fd, STDIN_FILENO) == -1) {
|
||||||
|
HiLog::Error(LABEL, "dup2 STDIN error: %{public}s", strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
};
|
||||||
|
|
||||||
|
// stdout
|
||||||
|
if (dup2(dev_null_fd, STDOUT_FILENO) == -1) {
|
||||||
|
HiLog::Error(LABEL, "dup2 STDOUT error: %{public}s", strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
};
|
||||||
|
|
||||||
|
// stderr
|
||||||
|
if (dup2(dev_null_fd, STDERR_FILENO) == -1) {
|
||||||
|
HiLog::Error(LABEL, "dup2 STDERR error: %{public}s", strerror(errno));
|
||||||
|
return (-errno);
|
||||||
|
};
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AppSpawnServer::SetCapabilities()
|
||||||
|
{
|
||||||
|
// init cap
|
||||||
|
__user_cap_header_struct cap_header;
|
||||||
|
if (memset_s(&cap_header, sizeof(cap_header), 0, sizeof(cap_header)) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "Failed to memset cap header");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cap_header.version = _LINUX_CAPABILITY_VERSION_3;
|
||||||
|
cap_header.pid = 0;
|
||||||
|
|
||||||
|
__user_cap_data_struct cap_data[2];
|
||||||
|
if (memset_s(&cap_data, sizeof(cap_data), 0, sizeof(cap_data)) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "Failed to memset cap data");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init inheritable permitted effective zero
|
||||||
|
#ifdef GRAPHIC_PERMISSION_CHECK
|
||||||
|
uint64_t inheriTable = 0;
|
||||||
|
uint64_t permitted = 0;
|
||||||
|
uint64_t effective = 0;
|
||||||
|
#else
|
||||||
|
uint64_t inheriTable = 0x3fffffffff;
|
||||||
|
uint64_t permitted = 0x3fffffffff;
|
||||||
|
uint64_t effective = 0x3fffffffff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cap_data[0].inheritable = inheriTable;
|
||||||
|
cap_data[1].inheritable = inheriTable >> BITLEN32;
|
||||||
|
cap_data[0].permitted = permitted;
|
||||||
|
cap_data[1].permitted = permitted >> BITLEN32;
|
||||||
|
cap_data[0].effective = effective;
|
||||||
|
cap_data[1].effective = effective >> BITLEN32;
|
||||||
|
|
||||||
|
// set capabilities
|
||||||
|
if (capset(&cap_header, &cap_data[0]) == -1) {
|
||||||
|
HiLog::Error(LABEL, "capset failed: %{public}s", strerror(errno));
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServer::SetRunning(bool isRunning)
|
||||||
|
{
|
||||||
|
isRunning_ = isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServer::SetServerSocket(const std::shared_ptr<ServerSocket> &serverSocket)
|
||||||
|
{
|
||||||
|
socket_ = serverSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppSpawnServer::SetAppProcProperty(int connectFd, const ClientSocket::AppProperty *appProperty, char *longProcName,
|
||||||
|
int64_t longProcNameLen, const int32_t fd[FDLEN2])
|
||||||
|
{
|
||||||
|
pid_t newPid = getpid();
|
||||||
|
HiLog::Debug(LABEL, "AppSpawnServer::Success to fork new process, pid = %{public}d", newPid);
|
||||||
|
// close socket connection in child process
|
||||||
|
socket_->CloseConnection(connectFd);
|
||||||
|
// close peer socket
|
||||||
|
socket_->CloseServerMonitor();
|
||||||
|
// close read end
|
||||||
|
close(fd[0]);
|
||||||
|
UninstallSigHandler();
|
||||||
|
|
||||||
|
// set process name
|
||||||
|
int32_t ret = ERR_OK;
|
||||||
|
ret = SetProcessName(longProcName, longProcNameLen, appProperty->processName, strlen(appProperty->processName) + 1);
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
HiLog::Error(LABEL, "SetProcessName error, ret %{public}d", ret);
|
||||||
|
write(fd[1], &ret, sizeof(ret));
|
||||||
|
close(fd[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GRAPHIC_PERMISSION_CHECK
|
||||||
|
// set uid gid
|
||||||
|
ret = SetUidGid(appProperty->uid, appProperty->gid, appProperty->gidTable, appProperty->gidCount);
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
HiLog::Error(LABEL, "SetUidGid error, ret %{public}d", ret);
|
||||||
|
write(fd[1], &ret, sizeof(ret));
|
||||||
|
close(fd[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set file descriptors
|
||||||
|
ret = SetFileDescriptors();
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
HiLog::Error(LABEL, "SetFileDescriptors error, ret %{public}d", ret);
|
||||||
|
write(fd[1], &ret, sizeof(ret));
|
||||||
|
close(fd[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set capabilities
|
||||||
|
ret = SetCapabilities();
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
HiLog::Error(LABEL, "SetCapabilities error, ret %{public}d", ret);
|
||||||
|
write(fd[1], &ret, sizeof(ret));
|
||||||
|
close(fd[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// child process init success, send to father process
|
||||||
|
write(fd[1], &ret, sizeof(ret));
|
||||||
|
close(fd[1]);
|
||||||
|
|
||||||
|
// start app process
|
||||||
|
AppExecFwk::MainThread::Start();
|
||||||
|
|
||||||
|
HiLog::Error(LABEL, "Failed to start process, pid = %{public}d", newPid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
34
src/main.cpp
Normal file
34
src/main.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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 "appspawn_server.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
|
||||||
|
int main(int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
if (argc > 0) {
|
||||||
|
// calculate child process long name size
|
||||||
|
uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
|
||||||
|
uintptr_t end = reinterpret_cast<uintptr_t>(strchr(argv[argc - 1], 0));
|
||||||
|
uintptr_t argvSize = end - start;
|
||||||
|
|
||||||
|
OHOS::AppSpawn::AppSpawnServer appspawnServer("AppSpawn");
|
||||||
|
appspawnServer.ServerMain(argv[0], argvSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
145
src/socket/appspawn_socket.cpp
Executable file
145
src/socket/appspawn_socket.cpp
Executable file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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 "appspawn_socket.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "pubdef.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnSocket"};
|
||||||
|
|
||||||
|
AppSpawnSocket::AppSpawnSocket(const std::string &name)
|
||||||
|
{
|
||||||
|
socketName_ = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSpawnSocket::~AppSpawnSocket()
|
||||||
|
{
|
||||||
|
if (socketFd_ > 0) {
|
||||||
|
CloseSocket(socketFd_);
|
||||||
|
socketFd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnSocket::GetSocketFd() const
|
||||||
|
{
|
||||||
|
return socketFd_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnSocket::PackSocketAddr()
|
||||||
|
{
|
||||||
|
if (socketName_.empty()) {
|
||||||
|
HiLog::Error(LABEL, "Invalid socket name: empty");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_)) != EOK) {
|
||||||
|
HiLog::Error(LABEL, "Failed to memset socket addr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socklen_t pathLen = socketDir_.length() + socketName_.length();
|
||||||
|
socklen_t pathSize = sizeof(socketAddr_.sun_path);
|
||||||
|
if (pathLen >= pathSize) {
|
||||||
|
HiLog::Error(LABEL, "Invalid socket name: '%s' too long", socketName_.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len =
|
||||||
|
snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s%s", socketDir_.c_str(), socketName_.c_str());
|
||||||
|
if (static_cast<int>(pathLen) != len) {
|
||||||
|
HiLog::Error(LABEL, "Failed to copy socket path");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socketAddr_.sun_family = AF_LOCAL;
|
||||||
|
socketAddrLen_ = offsetof(struct sockaddr_un, sun_path) + pathLen + 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnSocket::CreateSocket()
|
||||||
|
{
|
||||||
|
int socketFd = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
|
||||||
|
if (socketFd < 0) {
|
||||||
|
HiLog::Error(LABEL, "Failed to create socket: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Debug(LABEL, "Created socket with fd %d", socketFd);
|
||||||
|
return socketFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnSocket::CloseSocket(int &socketFd)
|
||||||
|
{
|
||||||
|
if (socketFd >= 0) {
|
||||||
|
HiLog::Debug(LABEL, "Closed socket with fd %d", socketFd);
|
||||||
|
close(socketFd);
|
||||||
|
socketFd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnSocket::ReadSocketMessage(int socketFd, void *buf, int len)
|
||||||
|
{
|
||||||
|
if (socketFd < 0 || len <= 0 || buf == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memset_s(buf, len, 0, len) != EOK) {
|
||||||
|
HiLog::Warn(LABEL, "Failed to memset read buf");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
|
||||||
|
if (rLen < 0) {
|
||||||
|
HiLog::Error(LABEL, "Read message from fd %d error %zd: %s", socketFd, rLen, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnSocket::WriteSocketMessage(int socketFd, const void *buf, int len)
|
||||||
|
{
|
||||||
|
if (socketFd < 0 || len <= 0 || buf == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t written = 0;
|
||||||
|
ssize_t remain = static_cast<ssize_t>(len);
|
||||||
|
const uint8_t *offset = reinterpret_cast<const uint8_t *>(buf);
|
||||||
|
for (ssize_t wLen; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
|
||||||
|
wLen = write(socketFd, offset, remain);
|
||||||
|
HiLog::Debug(LABEL, "socket fd %d, wLen %zd", socketFd, wLen);
|
||||||
|
if ((wLen <= 0) && (errno != EINTR)) {
|
||||||
|
HiLog::Error(LABEL, "Failed to write message to fd %d, error %zd: %s", socketFd, wLen, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
99
src/socket/client_socket.cpp
Normal file
99
src/socket/client_socket.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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 "client_socket.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "ClientSocket"};
|
||||||
|
|
||||||
|
ClientSocket::ClientSocket(const std::string &client) : AppSpawnSocket(client)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int ClientSocket::CreateClient()
|
||||||
|
{
|
||||||
|
if (socketFd_ < 0) {
|
||||||
|
socketFd_ = CreateSocket();
|
||||||
|
if (socketFd_ < 0) {
|
||||||
|
HiLog::Error(LABEL, "Client: Create socket failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Debug(LABEL, "Client: CreateClient socket fd %d", socketFd_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientSocket::CloseClient()
|
||||||
|
{
|
||||||
|
if (socketFd_ < 0) {
|
||||||
|
HiLog::Error(LABEL, "Client: Invalid connectFd %d", socketFd_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseSocket(socketFd_);
|
||||||
|
socketFd_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientSocket::ConnectSocket(int connectFd)
|
||||||
|
{
|
||||||
|
if (connectFd < 0) {
|
||||||
|
HiLog::Error(LABEL, "Client: Invalid socket fd: %d", connectFd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PackSocketAddr() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((setsockopt(connectFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0) ||
|
||||||
|
(setsockopt(connectFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0)) {
|
||||||
|
HiLog::Warn(LABEL, "Client: Failed to set opt of socket %d, err %s", connectFd, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(connectFd, reinterpret_cast<struct sockaddr *>(&socketAddr_), socketAddrLen_) < 0) {
|
||||||
|
HiLog::Warn(LABEL, "Client: Connect on socket fd %d, failed: %s", connectFd, strerror(errno));
|
||||||
|
CloseSocket(connectFd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Debug(LABEL, "Client: Connected on socket fd %d, name '%s'", connectFd, socketAddr_.sun_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientSocket::ConnectSocket()
|
||||||
|
{
|
||||||
|
return ConnectSocket(socketFd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientSocket::WriteSocketMessage(const void *buf, int len)
|
||||||
|
{
|
||||||
|
return WriteSocketMessage(socketFd_, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ClientSocket::ReadSocketMessage(void *buf, int len)
|
||||||
|
{
|
||||||
|
return ReadSocketMessage(socketFd_, buf, len);
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
216
src/socket/server_socket.cpp
Normal file
216
src/socket/server_socket.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* 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 "server_socket.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "ServerSocket"};
|
||||||
|
|
||||||
|
ServerSocket::ServerSocket(const std::string &server) : AppSpawnSocket(server)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ServerSocket::~ServerSocket()
|
||||||
|
{
|
||||||
|
CloseServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::VerifyConnection(int connectFd)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutexConnect_);
|
||||||
|
|
||||||
|
std::vector<int>::iterator it = find(connectFds_.begin(), connectFds_.end(), connectFd);
|
||||||
|
if (it == connectFds_.end()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseConnection(int connectFd)
|
||||||
|
{
|
||||||
|
if (connectFd < 0) {
|
||||||
|
HiLog::Error(LABEL, "Server: Invalid connectFd %d", connectFd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(mutexConnect_);
|
||||||
|
|
||||||
|
std::vector<int>::iterator it = find(connectFds_.begin(), connectFds_.end(), connectFd);
|
||||||
|
if (it == connectFds_.end()) {
|
||||||
|
close(connectFd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(connectFd);
|
||||||
|
connectFds_.erase(it);
|
||||||
|
HiLog::Debug(LABEL, "Server: Erase connect fd %d from list", connectFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::SaveConnection(int connectFd)
|
||||||
|
{
|
||||||
|
if (connectFd >= 0) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutexConnect_);
|
||||||
|
connectFds_.push_back(connectFd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseServer()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutexConnect_);
|
||||||
|
|
||||||
|
for (const int &fd : connectFds_) {
|
||||||
|
HiLog::Debug(LABEL, "Server: Closed connection fd %d", fd);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
connectFds_.clear();
|
||||||
|
if (socketFd_ >= 0) {
|
||||||
|
CloseSocket(socketFd_);
|
||||||
|
socketFd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseServerMonitor()
|
||||||
|
{
|
||||||
|
if (socketFd_ >= 0) {
|
||||||
|
CloseSocket(socketFd_);
|
||||||
|
socketFd_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::BindSocket(int connectFd)
|
||||||
|
{
|
||||||
|
if (connectFd < 0) {
|
||||||
|
HiLog::Error(LABEL, "Server: Invalid socket fd: %d", connectFd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PackSocketAddr() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((unlink(socketAddr_.sun_path) != 0) && (errno != ENOENT)) {
|
||||||
|
HiLog::Error(LABEL, "Server: Failed to unlink, err %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int reuseAddr = 0;
|
||||||
|
if ((setsockopt(connectFd, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) != 0) ||
|
||||||
|
(setsockopt(connectFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0) ||
|
||||||
|
(setsockopt(connectFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0)) {
|
||||||
|
HiLog::Warn(LABEL, "Server: Failed to set opt of socket %d, err %s", connectFd, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(connectFd, reinterpret_cast<struct sockaddr *>(&socketAddr_), socketAddrLen_) < 0) {
|
||||||
|
HiLog::Error(LABEL, "Server: Bind socket fd %d, failed: %s", connectFd, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chown(socketAddr_.sun_path, AID_ROOT, AID_SYSTEM)) {
|
||||||
|
HiLog::Error(LABEL, "Server: failed to chown socket fd %d, failed: %s", connectFd, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (chmod(socketAddr_.sun_path, SOCKET_PERM)) {
|
||||||
|
HiLog::Error(LABEL, "Server: failed to chmod socket fd %d, failed: %s", connectFd, strerror(errno));
|
||||||
|
if ((unlink(socketAddr_.sun_path) != 0) && (errno != ENOENT)) {
|
||||||
|
HiLog::Error(LABEL, "Server: Failed to unlink, err %s", strerror(errno));
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
HiLog::Debug(LABEL, "Server: Bind socket fd %d", connectFd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::RegisterServerSocket(int &connectFd)
|
||||||
|
{
|
||||||
|
if (socketName_.empty()) {
|
||||||
|
HiLog::Error(LABEL, "Server: Invalid socket name: empty");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectFd = CreateSocket();
|
||||||
|
if (connectFd < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((BindSocket(connectFd) != 0) || (listen(connectFd, listenBacklog_) < 0)) {
|
||||||
|
HiLog::Error(LABEL,
|
||||||
|
"Server: Register socket fd %d with backlog %d error: %s",
|
||||||
|
connectFd,
|
||||||
|
listenBacklog_,
|
||||||
|
strerror(errno));
|
||||||
|
close(connectFd);
|
||||||
|
connectFd = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Debug(LABEL, "Server: Suc to register server socket fd %d", connectFd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::RegisterServerSocket()
|
||||||
|
{
|
||||||
|
if (socketFd_ >= 0) {
|
||||||
|
HiLog::Info(LABEL, "Server: Already register server socket %d", socketFd_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RegisterServerSocket(socketFd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::WaitForConnection(int connectFd)
|
||||||
|
{
|
||||||
|
if (connectFd < 0) {
|
||||||
|
HiLog::Error(LABEL, "Server: Invalid args: connectFd %d", connectFd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_un clientAddr;
|
||||||
|
socklen_t clientLen = sizeof(clientAddr);
|
||||||
|
if (memset_s(&clientAddr, clientLen, 0, clientLen) != EOK) {
|
||||||
|
HiLog::Warn(LABEL, "Server: Failed to memset client addr");
|
||||||
|
}
|
||||||
|
|
||||||
|
int connFd = accept(connectFd, reinterpret_cast<struct sockaddr *>(&clientAddr), &clientLen);
|
||||||
|
if (connFd < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((setsockopt(connFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) < 0) ||
|
||||||
|
(setsockopt(connFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) < 0)) {
|
||||||
|
HiLog::Warn(LABEL, "Server: Failed to set opt of Connection %d, err %s", connFd, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Debug(LABEL, "Server: Connection accepted, connect fd %d", connFd);
|
||||||
|
return connFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::WaitForConnection()
|
||||||
|
{
|
||||||
|
int connectFd = WaitForConnection(socketFd_);
|
||||||
|
SaveConnection(connectFd);
|
||||||
|
|
||||||
|
return connectFd;
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
67
test/BUILD.gn
Normal file
67
test/BUILD.gn
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
"unittest/app_spawn_msg_peer_test:unittest",
|
||||||
|
"unittest/app_spawn_server_test:unittest",
|
||||||
|
"unittest/app_spawn_socket_test:unittest",
|
||||||
|
"unittest/client_socket_test:unittest",
|
||||||
|
"unittest/server_socket_test:unittest",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("moduletest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ "moduletest:moduletest" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
config("appspawn_test_config") {
|
||||||
|
configs = []
|
||||||
|
|
||||||
|
defines = []
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"${appspawn_path}/test/mock/include",
|
||||||
|
"${appspawn_path}/include",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_source_set("appspawn_test_source") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
sources = []
|
||||||
|
|
||||||
|
include_dirs = [ "//third_party/json/include" ]
|
||||||
|
|
||||||
|
public_configs = [
|
||||||
|
"//utils/native/base:utils_config",
|
||||||
|
":appspawn_test_config",
|
||||||
|
]
|
||||||
|
|
||||||
|
public_deps = [
|
||||||
|
"//third_party/googletest:gmock_main",
|
||||||
|
"//third_party/googletest:gtest_main",
|
||||||
|
"//utils/native/base:utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = []
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
32
test/mock/include/main_thread.h
Normal file
32
test/mock/include/main_thread.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FOUNDATION_APPEXECFWK_MAIN_THREAD_H
|
||||||
|
#define FOUNDATION_APPEXECFWK_MAIN_THREAD_H
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppExecFwk {
|
||||||
|
|
||||||
|
class MainThread {
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainThread() = default;
|
||||||
|
virtual ~MainThread() = default;
|
||||||
|
|
||||||
|
static void Start();
|
||||||
|
};
|
||||||
|
} // namespace AppExecFwk
|
||||||
|
} // namespace OHOS
|
||||||
|
#endif // MOCK_FOUNDATION_APPEXECFWK_MAIN_THREAD_H
|
36
test/mock/include/mock_client_socket.h
Normal file
36
test/mock/include/mock_client_socket.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 "client_socket.h"
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
|
||||||
|
class MockClientSocket : public ClientSocket {
|
||||||
|
public:
|
||||||
|
virtual ~MockClientSocket() = default;
|
||||||
|
MockClientSocket() : ClientSocket("MockClientSocket"){};
|
||||||
|
|
||||||
|
MOCK_METHOD0(CreateClient, int32_t());
|
||||||
|
MOCK_METHOD0(CloseClient, void());
|
||||||
|
MOCK_METHOD1(ConnectSocket, int32_t(int32_t socketFD));
|
||||||
|
MOCK_METHOD0(ConnectSocket, int32_t());
|
||||||
|
MOCK_METHOD2(WriteSocketMessage, int32_t(const void *buf, int32_t len));
|
||||||
|
MOCK_METHOD2(ReadSocketMessage, int32_t(void *buf, int32_t len));
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
133
test/mock/include/mock_server_socket.h
Normal file
133
test/mock/include/mock_server_socket.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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 "server_socket.h"
|
||||||
|
#include "client_socket.h"
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "securec.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
|
||||||
|
static constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "MockServerSocket"};
|
||||||
|
|
||||||
|
class MockServerSocket : public ServerSocket {
|
||||||
|
public:
|
||||||
|
MockServerSocket() = delete;
|
||||||
|
virtual ~MockServerSocket() = default;
|
||||||
|
MockServerSocket(const std::string &server) : ServerSocket(server){};
|
||||||
|
|
||||||
|
MOCK_METHOD1(SaveConnection, void(int32_t connectFd));
|
||||||
|
MOCK_METHOD1(CloseConnection, void(int32_t connectFd));
|
||||||
|
MOCK_METHOD0(CloseServer, void());
|
||||||
|
MOCK_METHOD0(CloseServerMonitor, void());
|
||||||
|
MOCK_METHOD0(RegisterServerSocket, int32_t());
|
||||||
|
MOCK_METHOD0(WaitForConnection, int32_t());
|
||||||
|
MOCK_METHOD1(VerifyConnection, int32_t(int32_t connectFd));
|
||||||
|
MOCK_METHOD3(ReadSocketMessage, int32_t(int32_t socketFd, void *buf, int32_t len));
|
||||||
|
MOCK_METHOD3(WriteSocketMessage, int32_t(int32_t socketFd, const void *buf, int32_t len));
|
||||||
|
|
||||||
|
int32_t ReadImplGidCountMax([[maybe_unused]]int32_t socketFd, void *buf, [[maybe_unused]]int32_t len)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
// assign AppProperty
|
||||||
|
ClientSocket::AppProperty *params = static_cast<ClientSocket::AppProperty *>(buf);
|
||||||
|
if (params == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params->uid = 0;
|
||||||
|
params->gid = 0;
|
||||||
|
(void)memset_s(params->gidTable, sizeof(params->gidTable), 0, sizeof(params->gidTable));
|
||||||
|
params->gidCount = ClientSocket::MAX_GIDS + 1;
|
||||||
|
std::string processName = "processName";
|
||||||
|
(void)memcpy_s(params->processName, sizeof(params->processName), processName.c_str(), processName.length());
|
||||||
|
std::string soPath = "soPath";
|
||||||
|
(void)memcpy_s(params->soPath, sizeof(params->soPath), soPath.c_str(), soPath.length());
|
||||||
|
|
||||||
|
return sizeof(ClientSocket::AppProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ReadImplProcessName([[maybe_unused]]int32_t socketFd, void *buf, [[maybe_unused]]int32_t len)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
// assign AppProperty
|
||||||
|
ClientSocket::AppProperty *params = static_cast<ClientSocket::AppProperty *>(buf);
|
||||||
|
if (params == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params->uid = 0;
|
||||||
|
params->gid = 0;
|
||||||
|
(void)memset_s(params->gidTable, sizeof(params->gidTable), 0, sizeof(params->gidTable));
|
||||||
|
params->gidCount = ClientSocket::MAX_GIDS;
|
||||||
|
std::string processName = "";
|
||||||
|
(void)memcpy_s(params->processName, sizeof(params->processName), processName.c_str(), processName.length());
|
||||||
|
std::string soPath = "soPath";
|
||||||
|
(void)memcpy_s(params->soPath, sizeof(params->soPath), soPath.c_str(), soPath.length());
|
||||||
|
|
||||||
|
return sizeof(ClientSocket::AppProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ReadImplValid([[maybe_unused]]int32_t socketFd, void *buf, [[maybe_unused]]int32_t len)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
// assign AppProperty
|
||||||
|
ClientSocket::AppProperty *params = static_cast<ClientSocket::AppProperty *>(buf);
|
||||||
|
if (params == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params->uid = 0;
|
||||||
|
params->gid = 0;
|
||||||
|
(void)memset_s(params->gidTable, sizeof(params->gidTable), 0, sizeof(params->gidTable));
|
||||||
|
params->gidCount = ClientSocket::MAX_GIDS;
|
||||||
|
std::string processName = "processName";
|
||||||
|
(void)memcpy_s(params->processName, sizeof(params->processName), processName.c_str(), processName.length());
|
||||||
|
std::string soPath = "soPath";
|
||||||
|
(void)memcpy_s(params->soPath, sizeof(params->soPath), soPath.c_str(), soPath.length());
|
||||||
|
|
||||||
|
return sizeof(ClientSocket::AppProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ReadImplValidLongProcessName([[maybe_unused]]int32_t socketFd, void *buf, [[maybe_unused]]int32_t len)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
// assign AppProperty
|
||||||
|
ClientSocket::AppProperty *params = static_cast<ClientSocket::AppProperty *>(buf);
|
||||||
|
if (params == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
params->uid = 0;
|
||||||
|
params->gid = 0;
|
||||||
|
(void)memset_s(params->gidTable, sizeof(params->gidTable), 0, sizeof(params->gidTable));
|
||||||
|
params->gidCount = ClientSocket::MAX_GIDS;
|
||||||
|
std::string processName = "ProcessName1234567890";
|
||||||
|
(void)memcpy_s(params->processName, sizeof(params->processName), processName.c_str(), processName.length());
|
||||||
|
std::string soPath = "soPath";
|
||||||
|
(void)memcpy_s(params->soPath, sizeof(params->soPath), soPath.c_str(), soPath.length());
|
||||||
|
|
||||||
|
return sizeof(ClientSocket::AppProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
79
test/mock/src/appspawn_msg_peer.cpp
Normal file
79
test/mock/src/appspawn_msg_peer.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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 "appspawn_msg_peer.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MockAppSpawnMsgPeer"};
|
||||||
|
|
||||||
|
AppSpawnMsgPeer::AppSpawnMsgPeer(const std::shared_ptr<ServerSocket> &socket, int connectFd)
|
||||||
|
: connectFd_(connectFd), socket_(socket)
|
||||||
|
{
|
||||||
|
buf_ = std::make_unique<int8_t[]>(sizeof(ClientSocket::AppProperty));
|
||||||
|
if (buf_ == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "buf_ is null pointer!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSpawnMsgPeer::~AppSpawnMsgPeer()
|
||||||
|
{
|
||||||
|
connectFd_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSocket::AppProperty *AppSpawnMsgPeer::GetMsg() const
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "GetMsg");
|
||||||
|
if (buf_ != nullptr) {
|
||||||
|
ClientSocket::AppProperty* appProperty = reinterpret_cast<ClientSocket::AppProperty *>(buf_.get());
|
||||||
|
appProperty->uid = 0;
|
||||||
|
appProperty->gid = 0;
|
||||||
|
(void)memset_s(appProperty->gidTable, sizeof(appProperty->gidTable), 0, sizeof(appProperty->gidTable));
|
||||||
|
appProperty->gidCount = ClientSocket::MAX_GIDS;
|
||||||
|
std::string processName = "processName";
|
||||||
|
(void)memcpy_s(appProperty->processName, sizeof(appProperty->processName),
|
||||||
|
processName.c_str(), processName.length());
|
||||||
|
std::string soPath = "soPath";
|
||||||
|
(void)memcpy_s(appProperty->soPath, sizeof(appProperty->soPath), soPath.c_str(), soPath.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<ClientSocket::AppProperty *>(buf_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::GetConnectFd() const
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "GetConnectFd");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::Response(pid_t pid)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "Response");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppSpawnMsgPeer::MsgPeer()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "MsgPeer");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
30
test/mock/src/main_thread.cpp
Normal file
30
test/mock/src/main_thread.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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 "main_thread.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppExecFwk {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MockMainThread"};
|
||||||
|
|
||||||
|
void MainThread::Start()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "Start");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AppExecFwk
|
||||||
|
} // namespace OHOS
|
94
test/mock/src/server_socket.cpp
Normal file
94
test/mock/src/server_socket.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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 "server_socket.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "client_socket.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
namespace OHOS {
|
||||||
|
namespace AppSpawn {
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "MockServerSocket"};
|
||||||
|
|
||||||
|
ServerSocket::ServerSocket(const std::string &server) : AppSpawnSocket(server)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ServerSocket::~ServerSocket()
|
||||||
|
{}
|
||||||
|
|
||||||
|
int ServerSocket::VerifyConnection(int connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "VerifyConnection");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseConnection(int connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "CloseConnection");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::SaveConnection(int connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "CloseConnection");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseServer()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "CloseServer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSocket::CloseServerMonitor()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "CloseServerMonitor");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::BindSocket(int connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "BindSocket");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::RegisterServerSocket(int &connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "RegisterServerSocket connectFd");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::RegisterServerSocket()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "RegisterServerSocket");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::WaitForConnection(int connectFd)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "WaitForConnection connectFd");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerSocket::WaitForConnection()
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "WaitForConnection");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace AppSpawn
|
||||||
|
} // namespace OHOS
|
49
test/moduletest/BUILD.gn
Normal file
49
test/moduletest/BUILD.gn
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_moduletest("AppSpawnModuleTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
sources = [ "${appspawn_path}/test/moduletest/appspawn_mst_test.cpp" ]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"//utils/native/base/include",
|
||||||
|
"//third_party/zlib/contrib/minizip",
|
||||||
|
"//third_party/zlib",
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/appexecfwk_base/include",
|
||||||
|
]
|
||||||
|
|
||||||
|
configs = [
|
||||||
|
"${appspawn_path}:appspawn_config",
|
||||||
|
"${appexecfwk_path}/services/appmgr:appmgr_config",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
"${appexecfwk_path}/interfaces/innerkits/appexecfwk_core:appexecfwk_core",
|
||||||
|
"${appexecfwk_path}/services/appmgr:libams",
|
||||||
|
"${appspawn_path}:appspawn_socket_client",
|
||||||
|
"//third_party/googletest:gtest_main",
|
||||||
|
"//utils/native/base:utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("moduletest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ ":AppSpawnModuleTest" ]
|
||||||
|
}
|
824
test/moduletest/appspawn_mst_test.cpp
Normal file
824
test/moduletest/appspawn_mst_test.cpp
Normal file
@ -0,0 +1,824 @@
|
|||||||
|
/*
|
||||||
|
* 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 "gtest/gtest.h"
|
||||||
|
#include "hilog/log.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
#include "app_spawn_client.h"
|
||||||
|
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS;
|
||||||
|
using namespace OHOS::AppExecFwk;
|
||||||
|
using namespace OHOS::HiviewDFX;
|
||||||
|
|
||||||
|
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnMST"};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const bool CHECK_OK = true;
|
||||||
|
const bool CHECK_ERROR = false;
|
||||||
|
const int32_t DEFAULT_PID = 0;
|
||||||
|
const int32_t FILE_PATH_SIZE = 50;
|
||||||
|
const int32_t CMD_SIZE = 50;
|
||||||
|
const int32_t BUFFER_SIZE = 512;
|
||||||
|
const int32_t BASE_TYPE = 10;
|
||||||
|
const int32_t CONNECT_RETRY_DELAY = 50 * 1000;
|
||||||
|
const int32_t CONNECT_RETRY_MAX_TIMES = 5;
|
||||||
|
const int32_t UID_POSITION_MOVE = 5;
|
||||||
|
const int32_t GID_POSITION_MOVE = 5;
|
||||||
|
const int32_t GROUPS_POSITION_MOVE = 8;
|
||||||
|
const char *DELIMITER_SPACE = " ";
|
||||||
|
const char *DELIMITER_NEWLINE = "\n";
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int32_t newPid = 0;
|
||||||
|
int32_t retryCount = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool checkFileIsExists(const char *filepath)
|
||||||
|
{
|
||||||
|
retryCount = 0;
|
||||||
|
while ((access(filepath, F_OK) != 0) && (retryCount < CONNECT_RETRY_MAX_TIMES)) {
|
||||||
|
usleep(CONNECT_RETRY_DELAY);
|
||||||
|
retryCount++;
|
||||||
|
}
|
||||||
|
GTEST_LOG_(INFO) << "retryCount :" << retryCount << ".";
|
||||||
|
if (retryCount < CONNECT_RETRY_MAX_TIMES) {
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readFileInfo(char *buffer, const int32_t &pid, const char *fileName)
|
||||||
|
{
|
||||||
|
// Set file path
|
||||||
|
char filePath[FILE_PATH_SIZE];
|
||||||
|
if (sprintf_s(filePath, sizeof(filePath), "/proc/%d/%s", pid, fileName) <= 0) {
|
||||||
|
HiLog::Error(LABEL, "filePath sprintf_s fail .");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
if (!checkFileIsExists(filePath)) {
|
||||||
|
HiLog::Error(LABEL, "file %{public}s is not exists .", fileName);
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
// Open file
|
||||||
|
int fd = open(filePath, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
HiLog::Error(LABEL, "file %{public}s open failed . error:%{publid}s", fileName, strerror(errno));
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
// Read file
|
||||||
|
int t = read(fd, buffer, BUFFER_SIZE);
|
||||||
|
if (t <= 0 || buffer == nullptr) {
|
||||||
|
HiLog::Info(LABEL, "read proc status file failed.");
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
HiLog::Info(LABEL, "buffer:\n %{public}s", buffer);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkUid(const int32_t &pid, const AppSpawnStartMsg ¶ms)
|
||||||
|
{
|
||||||
|
if (readFileInfo(buffer, pid, "status")) {
|
||||||
|
// Move to Uid position
|
||||||
|
char *uidPtr = strstr(buffer, "Uid") + UID_POSITION_MOVE;
|
||||||
|
if (uidPtr == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "get Uid info failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
if (strlen(uidPtr) > UID_POSITION_MOVE){
|
||||||
|
uidPtr = uidPtr + UID_POSITION_MOVE;
|
||||||
|
}
|
||||||
|
int32_t uid = (int32_t)strtol(uidPtr, NULL, BASE_TYPE);
|
||||||
|
HiLog::Info(LABEL, "new proc(%{public}d) uid = %{public}d, setUid=%{public}d.", pid, uid, params.uid);
|
||||||
|
if (uid == params.uid) {
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkGid(const int32_t &pid, const AppSpawnStartMsg ¶ms)
|
||||||
|
{
|
||||||
|
if (readFileInfo(buffer, pid, "status")) {
|
||||||
|
// Move to Gid position
|
||||||
|
char *gidPtr = strstr(buffer, "Gid");
|
||||||
|
if (gidPtr == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "get Gid info failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
if (strlen(gidPtr) > GID_POSITION_MOVE){
|
||||||
|
gidPtr = gidPtr + GID_POSITION_MOVE;
|
||||||
|
}
|
||||||
|
int32_t gid = (int32_t)strtol(gidPtr, NULL, BASE_TYPE);
|
||||||
|
HiLog::Info(LABEL, "new proc(%{public}d) gid = %{public}d, setGid=%{public}d.", pid, gid, params.gid);
|
||||||
|
if (gid == params.gid) {
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
std::size_t getGids(const int32_t &pid, std::vector<int32_t> &gids)
|
||||||
|
{
|
||||||
|
if (readFileInfo(buffer, pid, "status")) {
|
||||||
|
// Move to Groups position
|
||||||
|
char *groupsPtr = strstr(buffer, "Groups");
|
||||||
|
if (groupsPtr == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "get Groups info failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
if (strlen(groupsPtr) > GROUPS_POSITION_MOVE){
|
||||||
|
groupsPtr = groupsPtr + GROUPS_POSITION_MOVE;
|
||||||
|
}
|
||||||
|
// Get the row content of Groups
|
||||||
|
char *saveptr = NULL;
|
||||||
|
char *line = strtok_r(groupsPtr , DELIMITER_NEWLINE, &saveptr);
|
||||||
|
if (line == nullptr) {
|
||||||
|
HiLog::Error(LABEL, "get Groups line info failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
// Get each gid and insert into vector
|
||||||
|
char *gid = strtok_r(line, DELIMITER_SPACE, &saveptr);
|
||||||
|
while (gid != nullptr) {
|
||||||
|
gids.push_back(atoi(gid));
|
||||||
|
gid = strtok_r(nullptr, DELIMITER_SPACE, &saveptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gids.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkGids(const int32_t &pid, const AppSpawnStartMsg ¶ms)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get Gids
|
||||||
|
std::vector<int32_t> gids;
|
||||||
|
std::size_t gCount = getGids(pid, gids);
|
||||||
|
if ((gCount == params.gids.size()) && (gids == params.gids)) {
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkGidsCount(const int32_t &pid, const AppSpawnStartMsg ¶ms)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Get GidsCount
|
||||||
|
std::vector<int32_t> gids;
|
||||||
|
std::size_t gCount = getGids(pid, gids);
|
||||||
|
if (gCount == params.gids.size()) {
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkProcName(const int32_t &pid, const AppSpawnStartMsg ¶ms)
|
||||||
|
{
|
||||||
|
FILE *fp = nullptr;
|
||||||
|
char cmd[CMD_SIZE];
|
||||||
|
if (sprintf_s(cmd, sizeof(cmd),"ps -o ARGS=CMD -p %d |grep -v CMD", pid) <= 0) {
|
||||||
|
HiLog::Error(LABEL, "cmd sprintf_s fail .");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
fp = popen(cmd, "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
HiLog::Error(LABEL, " popen function call failed .");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
char procName[BUFFER_SIZE];
|
||||||
|
if (fgets(procName, sizeof(procName), fp) != nullptr) {
|
||||||
|
for (unsigned int i = 0; i < sizeof(procName); i++) {
|
||||||
|
if (procName[i] == '\n') {
|
||||||
|
procName[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GTEST_LOG_(INFO) << "strcmp"
|
||||||
|
<< " :" << strcmp(params.procName.c_str(), procName) << ".";
|
||||||
|
|
||||||
|
if (params.procName.compare(0,params.procName.size(),procName,params.procName.size()) == 0) {
|
||||||
|
pclose(fp);
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
HiLog::Error(LABEL, " procName=%{public}s, params.procName=%{public}s.", procName, params.procName.c_str());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
HiLog::Error(LABEL, "Getting procName failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(fp);
|
||||||
|
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
bool checkProcessIsDestroyed(const int32_t &pid)
|
||||||
|
{
|
||||||
|
char filePath[FILE_PATH_SIZE];
|
||||||
|
if (sprintf_s(filePath,sizeof(filePath), "/proc/%d", pid) <= 0) {
|
||||||
|
HiLog::Error(LABEL, "filePath sprintf_s fail .");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkFileIsExists(filePath)) {
|
||||||
|
HiLog::Error(LABEL, "File %{public}d is not exists .", pid);
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkAppspawnPID()
|
||||||
|
{
|
||||||
|
FILE *fp = nullptr;
|
||||||
|
fp = popen("pidof appspawn", "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
HiLog::Error(LABEL, " popen function call failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
char pid[BUFFER_SIZE];
|
||||||
|
if (fgets(pid, sizeof(pid), fp) != nullptr) {
|
||||||
|
pclose(fp);
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HiLog::Error(LABEL, "Getting Pid failed.");
|
||||||
|
|
||||||
|
pclose(fp);
|
||||||
|
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool startAppspawn()
|
||||||
|
{
|
||||||
|
FILE *fp = nullptr;
|
||||||
|
fp = popen("/system/bin/appspawn&", "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
HiLog::Error(LABEL, " popen function call failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(fp);
|
||||||
|
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stopAppspawn()
|
||||||
|
{
|
||||||
|
FILE *fp = nullptr;
|
||||||
|
fp = popen("kill -9 $(pidof appspawn)", "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
HiLog::Error(LABEL, " popen function call failed.");
|
||||||
|
return CHECK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(fp);
|
||||||
|
|
||||||
|
return CHECK_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppSpawnModuleTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
};
|
||||||
|
|
||||||
|
void AppSpawnModuleTest::SetUpTestCase()
|
||||||
|
{
|
||||||
|
if (!checkAppspawnPID()) {
|
||||||
|
EXPECT_EQ(startAppspawn(), CHECK_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnModuleTest::TearDownTestCase()
|
||||||
|
{
|
||||||
|
if (checkAppspawnPID()) {
|
||||||
|
EXPECT_EQ(stopAppspawn(), CHECK_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnModuleTest::SetUp()
|
||||||
|
{
|
||||||
|
newPid = 0;
|
||||||
|
EXPECT_EQ(memset_s(buffer, sizeof(buffer), 0x00, BUFFER_SIZE), EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnModuleTest::TearDown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: Listen
|
||||||
|
* SubFunction: Message listener
|
||||||
|
* FunctionPoints: Process start message monitoring
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Query the process of appspawn through the ps command
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_listen_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_listen_001 start");
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkAppspawnPID());
|
||||||
|
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_listen_001 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: Listen
|
||||||
|
* SubFunction: Message listener
|
||||||
|
* FunctionPoints: Process start message monitoring.
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_listen_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_listen_002 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_listen_002 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: Fork
|
||||||
|
* SubFunction: fork process
|
||||||
|
* FunctionPoints: Fork the process and run the App object.
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_fork_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_fork_001 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-fork_001", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_fork_001 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: Fork
|
||||||
|
* SubFunction: fork process
|
||||||
|
* FunctionPoints: Fork the process and run the App object.
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_fork_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_fork_002 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-fork_002", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_fork_002 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_001 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_001", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkUid(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_001 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_002 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_002", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGid(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_002 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_003 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_003", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGids(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_003 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_004 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_004", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGidsCount(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_004 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_005 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_005", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkUid(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_005 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_006 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_006", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGid(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_006 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_007 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_007", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGids(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_007 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: SetUid
|
||||||
|
* SubFunction: Set child process permissions
|
||||||
|
* FunctionPoints: Set the permissions of the child process to increase the priority of the new process
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setUid_008, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_008 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setUid_008", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(CHECK_OK, checkGidsCount(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setUid_008 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: setProcName
|
||||||
|
* SubFunction: Set process name
|
||||||
|
* FunctionPoints: Set process information .
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_DEFAULT
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setProcName_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setProcName_001 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setProcName_001", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
// Check new app proc name
|
||||||
|
EXPECT_EQ(CHECK_OK, checkProcName(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setProcName_001 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: setProcName
|
||||||
|
* SubFunction: Set process name
|
||||||
|
* FunctionPoints: Set process information .
|
||||||
|
* EnvConditions: AppSpawn main process has started.
|
||||||
|
* The socket server has been established.
|
||||||
|
* CaseDescription: 1. Establish a socket client and connect with the Appspawn server
|
||||||
|
* 2. Send the message and the message format is correct, the message type is APP_TYPE_NATIVE
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_setProcName_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setProcName_002 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-setProcName_002", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
// Check new app proc name
|
||||||
|
EXPECT_EQ(CHECK_OK, checkProcName(newPid, params));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_setProcName_002 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: recycleProc
|
||||||
|
* SubFunction: Recycling process
|
||||||
|
* FunctionPoints: Recycling zombie processes.
|
||||||
|
* EnvConditions: Start a js ability
|
||||||
|
* CaseDescription: 1. Use the command kill to kill the process pid of the ability
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_recycleProc_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_recycleProc_001 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-recycleProc_001", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, kill(newPid, SIGKILL));
|
||||||
|
newPid = DEFAULT_PID;
|
||||||
|
|
||||||
|
// Check Process Is Destroyed
|
||||||
|
EXPECT_EQ(CHECK_OK, checkProcessIsDestroyed(newPid));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_recycleProc_001 end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: recycleProc
|
||||||
|
* SubFunction: Recycling process
|
||||||
|
* FunctionPoints: Recycling zombie processes
|
||||||
|
* EnvConditions: Start a native ability .
|
||||||
|
* CaseDescription: 1. Use the command kill to kill the process pid of the ability
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnModuleTest, AppSpawn_HF_recycleProc_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_recycleProc_002 start");
|
||||||
|
std::shared_ptr<AppSpawnClient> appSpawnClient = std::make_shared<AppSpawnClient>();
|
||||||
|
std::shared_ptr<AppSpawnSocket> appSpawnSocket = std::make_shared<AppSpawnSocket>();
|
||||||
|
appSpawnClient->SetSocket(appSpawnSocket);
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnClient->OpenConnection());
|
||||||
|
AppSpawnStartMsg params = {10003, 10004, {10003, 10004}, "processName-recycleProc_002", "soPath"};
|
||||||
|
|
||||||
|
appSpawnClient->StartProcess(params, newPid);
|
||||||
|
// 0 < newPid, new process fork success
|
||||||
|
GTEST_LOG_(INFO) << "newPid :" << newPid << ".";
|
||||||
|
EXPECT_LT(DEFAULT_PID, newPid);
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, kill(newPid, SIGKILL));
|
||||||
|
newPid = DEFAULT_PID;
|
||||||
|
|
||||||
|
// Check Process Is Destroyed
|
||||||
|
EXPECT_EQ(CHECK_OK, checkProcessIsDestroyed(newPid));
|
||||||
|
|
||||||
|
EXPECT_EQ(ERR_OK, appSpawnSocket->OpenAppSpawnConnection());
|
||||||
|
appSpawnClient->CloseConnection();
|
||||||
|
EXPECT_EQ(SpawnConnectionState::STATE_NOT_CONNECT, appSpawnClient->QueryConnectionState());
|
||||||
|
HiLog::Info(LABEL, "AppSpawn_HF_recycleProc_002 end");
|
||||||
|
}
|
39
test/unittest/app_spawn_msg_peer_test/BUILD.gn
Normal file
39
test/unittest/app_spawn_msg_peer_test/BUILD.gn
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_unittest("AppSpawnMsgPeerTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/appspawn_msg_peer.cpp",
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/server_socket.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [ "app_spawn_msg_peer_test.cpp" ]
|
||||||
|
|
||||||
|
configs = [ "${appspawn_path}:appspawn_config" ]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ ":AppSpawnMsgPeerTest" ]
|
||||||
|
}
|
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* 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 <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "mock_server_socket.h"
|
||||||
|
#include "appspawn_msg_peer.h"
|
||||||
|
#include "server_socket.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class AppSpawnMsgPeerTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
};
|
||||||
|
|
||||||
|
void AppSpawnMsgPeerTest::SetUpTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnMsgPeerTest::TearDownTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnMsgPeerTest::SetUp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnMsgPeerTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: GetConnectFd & GetMsg
|
||||||
|
* FunctionPoints: simple function branch coverage
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify if new AppSpawnMsgPeer with the invalid params and the function GetConnectFd and GetMsg will
|
||||||
|
* return default value.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_001 start";
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSocket> serverSocket = std::make_shared<ServerSocket>("ServerSocket");
|
||||||
|
int32_t connectFd = -1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(serverSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->GetConnectFd());
|
||||||
|
EXPECT_EQ(nullptr, appSpawnMsgPeer->GetMsg());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: MsgPeer
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function MsgPeer can check the invalid connect fd.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_002 start";
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSocket> serverSocket = std::make_shared<ServerSocket>("ServerSocket");
|
||||||
|
int32_t connectFd = -1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(serverSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->MsgPeer());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: MsgPeer
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function MsgPeer can check the invalid server socket.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_003 start";
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSocket> serverSocket = nullptr;
|
||||||
|
int32_t connectFd = 1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(serverSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->MsgPeer());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_003 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: Response
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function Response can check the invalid connect fd.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_004 start";
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSocket> serverSocket = std::make_shared<ServerSocket>("ServerSocket");
|
||||||
|
int32_t connectFd = -1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(serverSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->Response(1));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_004 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: Response
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function Response can check the invalid server socket.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_005 start";
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSocket> serverSocket = nullptr;
|
||||||
|
int32_t connectFd = 1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(serverSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->Response(1));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_005 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: MsgPeer
|
||||||
|
* FunctionPoints: read socket message
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function MsgPeer can check the the invalid message read.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_006 start";
|
||||||
|
|
||||||
|
std::shared_ptr<MockServerSocket> mockServerSocket = std::make_shared<MockServerSocket>("MockServerSocket");
|
||||||
|
int32_t connectFd = 1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(mockServerSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_CALL(*mockServerSocket, ReadSocketMessage(_, _, _)).WillOnce(Return(-1));
|
||||||
|
EXPECT_CALL(*mockServerSocket, CloseConnection(_)).WillOnce(Return());
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->MsgPeer());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_006 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: MsgPeer
|
||||||
|
* FunctionPoints: read socket message
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function MsgPeer can check the the too long message read.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_007 start";
|
||||||
|
|
||||||
|
std::shared_ptr<MockServerSocket> mockServerSocket = std::make_shared<MockServerSocket>("MockServerSocket");
|
||||||
|
int32_t connectFd = 1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(mockServerSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_CALL(*mockServerSocket, ReadSocketMessage(_, _, _)).WillOnce(Return(sizeof(ClientSocket::AppProperty) + 1));
|
||||||
|
EXPECT_CALL(*mockServerSocket, CloseConnection(_)).WillOnce(Return());
|
||||||
|
EXPECT_EQ(-1, appSpawnMsgPeer->MsgPeer());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_007 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnMsgPeer
|
||||||
|
* SubFunction: MsgPeer
|
||||||
|
* FunctionPoints: read socket message
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function MsgPeer read socket message.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnMsgPeerTest, App_Spawn_Msg_Peer_008, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_008 start";
|
||||||
|
|
||||||
|
std::shared_ptr<MockServerSocket> mockServerSocket = std::make_shared<MockServerSocket>("MockServerSocket");
|
||||||
|
int32_t connectFd = 1;
|
||||||
|
std::unique_ptr<AppSpawnMsgPeer> appSpawnMsgPeer = std::make_unique<AppSpawnMsgPeer>(mockServerSocket, connectFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(nullptr, appSpawnMsgPeer->GetMsg());
|
||||||
|
EXPECT_CALL(*mockServerSocket, ReadSocketMessage(_, _, _))
|
||||||
|
.WillOnce(Invoke(mockServerSocket.get(), &MockServerSocket::ReadImplValid));
|
||||||
|
EXPECT_CALL(*mockServerSocket, CloseConnection(_)).WillOnce(Return());
|
||||||
|
EXPECT_EQ(0, appSpawnMsgPeer->MsgPeer());
|
||||||
|
EXPECT_NE(nullptr, appSpawnMsgPeer->GetMsg());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Msg_Peer_008 end";
|
||||||
|
}
|
74
test/unittest/app_spawn_server_test/BUILD.gn
Executable file
74
test/unittest/app_spawn_server_test/BUILD.gn
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_unittest("AppSpawnServerOverrideTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
include_dirs = []
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/appspawn_server.cpp",
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [
|
||||||
|
"${appspawn_path}/test/mock/src/appspawn_msg_peer.cpp",
|
||||||
|
"${appspawn_path}/test/mock/src/main_thread.cpp",
|
||||||
|
"${appspawn_path}/test/mock/src/server_socket.cpp",
|
||||||
|
"app_spawn_server_override_test.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [
|
||||||
|
"hiviewdfx_hilog_native:libhilog",
|
||||||
|
"ipc:ipc_core",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
ohos_unittest("AppSpawnServerMockTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
include_dirs = []
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/appspawn_msg_peer.cpp",
|
||||||
|
"${appspawn_path}/src/appspawn_server.cpp",
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/server_socket.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [
|
||||||
|
"${appspawn_path}/test/mock/src/main_thread.cpp",
|
||||||
|
"app_spawn_server_mock_test.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [
|
||||||
|
"hiviewdfx_hilog_native:libhilog",
|
||||||
|
"ipc:ipc_core",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
":AppSpawnServerMockTest",
|
||||||
|
":AppSpawnServerOverrideTest",
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* 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 <gtest/gtest.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "mock_server_socket.h"
|
||||||
|
|
||||||
|
// redefine private and protected since testcase need to invoke and test private function
|
||||||
|
#define private public
|
||||||
|
#define protected public
|
||||||
|
#include "appspawn_server.h"
|
||||||
|
#undef private
|
||||||
|
#undef protected
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class AppSpawnServerMockTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr int TEST_WAIT_TIME = 50 * 1000; // 50 ms
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<AppSpawnServer> appSpawnServer_;
|
||||||
|
std::shared_ptr<MockServerSocket> mockServerSocket_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AppSpawnServerMockTest::SetUpTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerMockTest::TearDownTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerMockTest::SetUp()
|
||||||
|
{
|
||||||
|
if (mockServerSocket_ == nullptr) {
|
||||||
|
mockServerSocket_ = std::make_shared<MockServerSocket>("MockServerSocket");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appSpawnServer_ == nullptr) {
|
||||||
|
appSpawnServer_ = std::make_unique<AppSpawnServer>("AppSpawnServerMockTest");
|
||||||
|
appSpawnServer_->SetServerSocket(mockServerSocket_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerMockTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: ServerMain
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify if the socket name is empty, the function ServerMain start fail.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerMockTest, App_Spawn_Server_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_001 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnServer> appSpawnServer = std::make_unique<AppSpawnServer>("");
|
||||||
|
char argv[20] = "LongNameTest";
|
||||||
|
EXPECT_EQ(false, appSpawnServer->ServerMain(argv, sizeof(argv)));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: ServerMain
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ServerMain can check the gidcount > max.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerMockTest, App_Spawn_Server_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_002 start";
|
||||||
|
|
||||||
|
char argv[20] = "LongNameTest";
|
||||||
|
|
||||||
|
testing::Mock::AllowLeak(mockServerSocket_.get());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, RegisterServerSocket()).WillOnce(Return(0));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, WaitForConnection()).WillRepeatedly(Return(1));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, SaveConnection(_)).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, ReadSocketMessage(_, _, _))
|
||||||
|
.WillRepeatedly(Invoke(mockServerSocket_.get(), &MockServerSocket::ReadImplGidCountMax));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, CloseConnection(_)).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, CloseServerMonitor()).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, WriteSocketMessage(_, _, _)).WillRepeatedly(Return(sizeof(pid_t)));
|
||||||
|
|
||||||
|
auto func = [&]() {
|
||||||
|
// wait ServerMain unit test case
|
||||||
|
usleep(AppSpawnServerMockTest::TEST_WAIT_TIME);
|
||||||
|
appSpawnServer_->SetRunning(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread(func).detach();
|
||||||
|
EXPECT_EQ(false, appSpawnServer_->ServerMain(argv, sizeof(argv)));
|
||||||
|
|
||||||
|
// wait release
|
||||||
|
usleep(AppSpawnServerMockTest::TEST_WAIT_TIME);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: ServerMain
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ServerMain can check the process name is empty.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerMockTest, App_Spawn_Server_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_003 start";
|
||||||
|
|
||||||
|
char argv[20] = "LongNameTest";
|
||||||
|
|
||||||
|
testing::Mock::AllowLeak(mockServerSocket_.get());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, RegisterServerSocket()).WillOnce(Return(0));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, WaitForConnection()).WillRepeatedly(Return(1));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, SaveConnection(_)).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, ReadSocketMessage(_, _, _))
|
||||||
|
.WillRepeatedly(Invoke(mockServerSocket_.get(), &MockServerSocket::ReadImplProcessName));
|
||||||
|
EXPECT_CALL(*mockServerSocket_, CloseConnection(_)).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, CloseServerMonitor()).WillRepeatedly(Return());
|
||||||
|
EXPECT_CALL(*mockServerSocket_, WriteSocketMessage(_, _, _)).WillRepeatedly(Return(sizeof(pid_t)));
|
||||||
|
|
||||||
|
auto func = [=]() {
|
||||||
|
// wait ServerMain unit test case
|
||||||
|
usleep(AppSpawnServerMockTest::TEST_WAIT_TIME);
|
||||||
|
appSpawnServer_->SetRunning(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread(func).detach();
|
||||||
|
EXPECT_EQ(false, appSpawnServer_->ServerMain(argv, sizeof(argv)));
|
||||||
|
|
||||||
|
// wait release
|
||||||
|
usleep(AppSpawnServerMockTest::TEST_WAIT_TIME);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_003 end";
|
||||||
|
}
|
@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* 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 <gtest/gtest.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// redefine private and protected since testcase need to invoke and test private function
|
||||||
|
#define private public
|
||||||
|
#define protected public
|
||||||
|
#include "appspawn_server.h"
|
||||||
|
#undef private
|
||||||
|
#undef protected
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class AppSpawnServerOverrideTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr int TEST_WAIT_TIME = 50 * 1000; // 50 ms
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<AppSpawnServer> appSpawnServer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AppSpawnServerOverrideTest::SetUpTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerOverrideTest::TearDownTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerOverrideTest::SetUp()
|
||||||
|
{
|
||||||
|
if (appSpawnServer_ == nullptr) {
|
||||||
|
appSpawnServer_ = std::make_unique<AppSpawnServer>("AppSpawnServerOverrideTest");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSpawnServerOverrideTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: ServerMain
|
||||||
|
* FunctionPoints: fork app process
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ServerMain fork app process success.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_001 start";
|
||||||
|
|
||||||
|
char argv[20] = "LongNameTest";
|
||||||
|
auto func = [&]() {
|
||||||
|
// wait ServerMain unit test case
|
||||||
|
usleep(AppSpawnServerOverrideTest::TEST_WAIT_TIME);
|
||||||
|
appSpawnServer_->SetRunning(false);
|
||||||
|
};
|
||||||
|
std::thread(func).detach();
|
||||||
|
EXPECT_EQ(false, appSpawnServer_->ServerMain(argv, sizeof(argv)));
|
||||||
|
|
||||||
|
// wait release
|
||||||
|
usleep(AppSpawnServerOverrideTest::TEST_WAIT_TIME);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and longProcName param is nullptr.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_002 start";
|
||||||
|
|
||||||
|
char* longProcName = nullptr;
|
||||||
|
int64_t longProcNameLen = sizeof(longProcName);
|
||||||
|
char processName[16] = "LongNameTest";
|
||||||
|
int32_t len = sizeof(processName);
|
||||||
|
|
||||||
|
EXPECT_EQ(-EINVAL, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and processName param is nullptr.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_003 start";
|
||||||
|
|
||||||
|
char longProcName[20] = "longProcName";
|
||||||
|
int64_t longProcNameLen = sizeof(longProcName);
|
||||||
|
char* processName = nullptr;
|
||||||
|
int32_t len = sizeof(processName);
|
||||||
|
|
||||||
|
EXPECT_EQ(-EINVAL, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_003 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and len param is 0.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_004 start";
|
||||||
|
|
||||||
|
char longProcName[20] = "longProcName";
|
||||||
|
int64_t longProcNameLen = sizeof(longProcName);
|
||||||
|
char processName[16] = "processName";
|
||||||
|
int32_t len = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ(-EINVAL, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_004 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and len param is -1.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_005 start";
|
||||||
|
|
||||||
|
char longProcName[20] = "longProcName";
|
||||||
|
int64_t longProcNameLen = sizeof(longProcName);
|
||||||
|
char processName[16] = "processName";
|
||||||
|
int32_t len = -1;
|
||||||
|
|
||||||
|
EXPECT_EQ(-EINVAL, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_005 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and processName length < 16.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_006 start";
|
||||||
|
|
||||||
|
char longProcName[20] = "longProcName";
|
||||||
|
int64_t longProcNameLen = sizeof(longProcName);
|
||||||
|
char processName[16] = "processName";
|
||||||
|
int32_t len = sizeof(processName);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_006 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnServer
|
||||||
|
* SubFunction: SetProcessName
|
||||||
|
* FunctionPoints: set process name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function SetProcessName and processName length > 16.
|
||||||
|
*/
|
||||||
|
HWTEST_F(AppSpawnServerOverrideTest, App_Spawn_Server_Override_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_007 start";
|
||||||
|
|
||||||
|
char longProcName[20] = "longProcName";
|
||||||
|
int64_t longProcNameLen = strlen(longProcName);
|
||||||
|
char processName[32] = "processName0123456789";
|
||||||
|
int32_t len = sizeof(processName);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, appSpawnServer_->SetProcessName(longProcName, longProcNameLen, processName, len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Server_Override_007 end";
|
||||||
|
}
|
35
test/unittest/app_spawn_socket_test/BUILD.gn
Normal file
35
test/unittest/app_spawn_socket_test/BUILD.gn
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_unittest("AppSpawnSocketTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
sources = [ "${appspawn_path}/src/socket/appspawn_socket.cpp" ]
|
||||||
|
|
||||||
|
sources += [ "app_spawn_socket_test.cpp" ]
|
||||||
|
|
||||||
|
configs = [ "${appspawn_path}:appspawn_config" ]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ ":AppSpawnSocketTest" ]
|
||||||
|
}
|
422
test/unittest/app_spawn_socket_test/app_spawn_socket_test.cpp
Normal file
422
test/unittest/app_spawn_socket_test/app_spawn_socket_test.cpp
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
/*
|
||||||
|
* 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 <gtest/gtest.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// redefine private and protected since testcase need to invoke and test private function
|
||||||
|
#define private public
|
||||||
|
#define protected public
|
||||||
|
#include "appspawn_socket.h"
|
||||||
|
#undef private
|
||||||
|
#undef protected
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class AppSpawnSocketTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr int TEST_WAIT_TIME = 100000;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AppSpawnSocketTest::SetUpTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnSocketTest::TearDownTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnSocketTest::SetUp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void AppSpawnSocketTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: CreateSocket & CloseSocket
|
||||||
|
* FunctionPoints: create socket and close socket.
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify if CreateSocket success then can close the socket.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_001 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->GetSocketFd());
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
EXPECT_LE(0, socketFd);
|
||||||
|
appSpawnSocket->CloseSocket(socketFd);
|
||||||
|
EXPECT_EQ(-1, socketFd);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: CloseSocket
|
||||||
|
* FunctionPoints: close the invalid socket fd.
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function CloseSocket don't close the socket which socket fd is invalid.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_002 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
int32_t socketFd = -2;
|
||||||
|
appSpawnSocket->CloseSocket(socketFd);
|
||||||
|
|
||||||
|
EXPECT_EQ(-2, socketFd);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: PackSocketAddr
|
||||||
|
* FunctionPoints: check the invalid socket name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function PackSocketAddr can check the empty socket name.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_003 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->PackSocketAddr());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_003 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: PackSocketAddr
|
||||||
|
* FunctionPoints: check the invalid socket name
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function PackSocketAddr can check too long socket name.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_004 start";
|
||||||
|
|
||||||
|
std::string invalidSocketName =
|
||||||
|
"InvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalid"
|
||||||
|
"InvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalid";
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>(invalidSocketName.c_str());
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->PackSocketAddr());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_004 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: PackSocketAddr
|
||||||
|
* FunctionPoints: pack socket address
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function PackSocketAddr can pack the socket address with valid socket name.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_005 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, appSpawnSocket->PackSocketAddr());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_005 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the invalid socket fd.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_006 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
|
||||||
|
int32_t socketFd = -1;
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(10);
|
||||||
|
ASSERT_FALSE(buff == nullptr);
|
||||||
|
int32_t len = 10;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->ReadSocketMessage(socketFd, buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_006 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the invalid buffer pointer.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_007 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::unique_ptr<uint8_t[]> buff = nullptr;
|
||||||
|
int32_t len = 10;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->ReadSocketMessage(socketFd, buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_007 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the buffer length is 0.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_008, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_008 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(10);
|
||||||
|
ASSERT_FALSE(buff == nullptr);
|
||||||
|
int32_t len = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->ReadSocketMessage(socketFd, buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_008 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the buffer length < 0.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_009, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_009 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(10);
|
||||||
|
ASSERT_FALSE(buff == nullptr);
|
||||||
|
int32_t len = -1;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->ReadSocketMessage(socketFd, buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_009 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: normal read data
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can read the normal message.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_010, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_010 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
std::string content = "hiworld";
|
||||||
|
int32_t len = content.length();
|
||||||
|
std::unique_ptr<int8_t[]> buff = std::make_unique<int8_t[]>(len);
|
||||||
|
ASSERT_FALSE(buff == nullptr);
|
||||||
|
int32_t fd[2] = {0, 0};
|
||||||
|
|
||||||
|
if (pipe(fd) == -1) {
|
||||||
|
GTEST_LOG_(WARNING) << "create pipe fail";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write(fd[1], content.c_str(), len);
|
||||||
|
|
||||||
|
EXPECT_EQ(len, appSpawnSocket->ReadSocketMessage(fd[0], buff.get(), len));
|
||||||
|
EXPECT_EQ(0, strncmp(content.c_str(), (const char *)(buff.get()), len));
|
||||||
|
|
||||||
|
// close pipe
|
||||||
|
close(fd[0]);
|
||||||
|
close(fd[1]);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_010 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the invalid socket fd.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_011, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_011 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
int32_t socketFd = -1;
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->WriteSocketMessage(socketFd, buff.c_str(), buff.length()));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_011 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the invalid buffer pointer.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_012, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_012 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::unique_ptr<uint8_t[]> buff = nullptr;
|
||||||
|
int32_t len = 10;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->WriteSocketMessage(socketFd, buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_012 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the buffer length is 0.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_013, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_013 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
int32_t len = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->WriteSocketMessage(socketFd, buff.c_str(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_013 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function ReadSocketMessage can check the buffer length < 0.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_014, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_014 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
auto socketFd = appSpawnSocket->CreateSocket();
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
int32_t len = -1;
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, appSpawnSocket->WriteSocketMessage(socketFd, buff.c_str(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_014 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: AppSpawnSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: normal write data
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can write the normal message.
|
||||||
|
*/
|
||||||
|
HWTEST(AppSpawnSocketTest, App_Spawn_Socket_015, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_015 start";
|
||||||
|
|
||||||
|
std::unique_ptr<AppSpawnSocket> appSpawnSocket = std::make_unique<AppSpawnSocket>("AppSpawnSocketTest");
|
||||||
|
ASSERT_FALSE(appSpawnSocket == nullptr);
|
||||||
|
std::string content = "hiworld";
|
||||||
|
int32_t len = content.length();
|
||||||
|
std::unique_ptr<int8_t[]> buff = std::make_unique<int8_t[]>(len);
|
||||||
|
ASSERT_FALSE(buff == nullptr);
|
||||||
|
int32_t fd[2] = {0, 0};
|
||||||
|
|
||||||
|
if (pipe(fd) == -1) {
|
||||||
|
GTEST_LOG_(WARNING) << "create pipe fail";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(len, appSpawnSocket->WriteSocketMessage(fd[1], content.c_str(), len));
|
||||||
|
read(fd[0], buff.get(), len);
|
||||||
|
EXPECT_EQ(0, strncmp(content.c_str(), (const char *)(buff.get()), len));
|
||||||
|
|
||||||
|
// close pipe
|
||||||
|
close(fd[0]);
|
||||||
|
close(fd[1]);
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "App_Spawn_Socket_015 end";
|
||||||
|
}
|
40
test/unittest/client_socket_test/BUILD.gn
Normal file
40
test/unittest/client_socket_test/BUILD.gn
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_unittest("ClientSocketTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
defines = [ "usleep(time) = MockSleep(time)" ]
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/client_socket.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [ "client_socket_test.cpp" ]
|
||||||
|
|
||||||
|
configs = [ "${appspawn_path}:appspawn_config" ]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ ":ClientSocketTest" ]
|
||||||
|
}
|
300
test/unittest/client_socket_test/client_socket_test.cpp
Normal file
300
test/unittest/client_socket_test/client_socket_test.cpp
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
* 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 <memory>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
// redefine private and protected since testcase need to invoke and test private function
|
||||||
|
#define private public
|
||||||
|
#define protected public
|
||||||
|
#include "client_socket.h"
|
||||||
|
#undef private
|
||||||
|
#undef protected
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class ClientSocketTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr int TEST_WAIT_TIME = 100000;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ClientSocketTest::SetUpTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ClientSocketTest::TearDownTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ClientSocketTest::SetUp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ClientSocketTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: CreateClient & ConnectSocket
|
||||||
|
* FunctionPoints: create client socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify although the client socket created success but don't create the server socket, the connect
|
||||||
|
* socket still fail.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_001 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
int32_t socketFd = clientSocket->GetSocketFd();
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_EQ(socketFd, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->ConnectSocket());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: ConnectSocket
|
||||||
|
* FunctionPoints: connect socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify connect socket fail when don't create client socket.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_002 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->ConnectSocket());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: write message
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify write message fail when don't create client socket.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_003 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, clientSocket->WriteSocketMessage(buff.c_str(), buff.length()));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_003 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the invalid buffer pointer.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_004 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
std::unique_ptr<uint8_t[]> buff = nullptr;
|
||||||
|
uint32_t len = 10;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->WriteSocketMessage(buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_004 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the buffer length is 0.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_005 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->WriteSocketMessage(buff.c_str(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_005 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: WriteSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the buffer length < 0.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_006 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
std::string buff = "hiworld";
|
||||||
|
uint32_t len = -1;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->WriteSocketMessage(buff.c_str(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_006 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: read message
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify read message fail when don't create client socket.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_007 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
int32_t len = 10;
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(len);
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, clientSocket->ReadSocketMessage(buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_007 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the invalid buffer pointer.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_008, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_008 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
int32_t len = 10;
|
||||||
|
std::unique_ptr<uint8_t[]> buff = nullptr;
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->ReadSocketMessage(buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_008 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the buffer length is 0.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_009, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_009 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
int32_t len = 0;
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(10);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->ReadSocketMessage(buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_009 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: ReadSocketMessage
|
||||||
|
* FunctionPoints: check params
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WriteSocketMessage can check the buffer length < 0.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_010, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_010 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
int32_t len = -1;
|
||||||
|
std::unique_ptr<uint8_t[]> buff = std::make_unique<uint8_t[]>(10);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(-1, clientSocket->ReadSocketMessage(buff.get(), len));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_010 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ClientSocket
|
||||||
|
* SubFunction: GetSocketFd
|
||||||
|
* FunctionPoints: close the socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function CloseClient can close the socket which socket fd has created.
|
||||||
|
*/
|
||||||
|
HWTEST(ClientSocketTest, Client_Socket_011, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_011 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ClientSocket> clientSocket = std::make_unique<ClientSocket>("ClientSocketTest");
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, clientSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(0, clientSocket->CreateClient());
|
||||||
|
EXPECT_LE(0, clientSocket->GetSocketFd());
|
||||||
|
clientSocket->CloseClient();
|
||||||
|
EXPECT_EQ(-1, clientSocket->GetSocketFd());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Client_Socket_011 end";
|
||||||
|
}
|
40
test/unittest/server_socket_test/BUILD.gn
Normal file
40
test/unittest/server_socket_test/BUILD.gn
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# 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("//base/startup/appspawn_standard/appspawn.gni")
|
||||||
|
import("//build/test.gni")
|
||||||
|
|
||||||
|
ohos_unittest("ServerSocketTest") {
|
||||||
|
module_out_path = "${module_output_path}"
|
||||||
|
|
||||||
|
defines = [ "usleep(time) = MockSleep(time)" ]
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"${appspawn_path}/src/socket/appspawn_socket.cpp",
|
||||||
|
"${appspawn_path}/src/socket/server_socket.cpp",
|
||||||
|
]
|
||||||
|
|
||||||
|
sources += [ "server_socket_test.cpp" ]
|
||||||
|
|
||||||
|
configs = [ "${appspawn_path}:appspawn_config" ]
|
||||||
|
|
||||||
|
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
|
||||||
|
|
||||||
|
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
group("unittest") {
|
||||||
|
testonly = true
|
||||||
|
|
||||||
|
deps = [ ":ServerSocketTest" ]
|
||||||
|
}
|
205
test/unittest/server_socket_test/server_socket_test.cpp
Normal file
205
test/unittest/server_socket_test/server_socket_test.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* 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 <memory>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
// redefine private and protected since testcase need to invoke and test private function
|
||||||
|
#define private public
|
||||||
|
#define protected public
|
||||||
|
#include "server_socket.h"
|
||||||
|
#undef private
|
||||||
|
#undef protected
|
||||||
|
|
||||||
|
#include "securec.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace testing::ext;
|
||||||
|
using namespace OHOS::AppSpawn;
|
||||||
|
|
||||||
|
class ServerSocketTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
static void SetUpTestCase();
|
||||||
|
static void TearDownTestCase();
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr int TEST_WAIT_TIME = 100000;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ServerSocketTest::SetUpTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ServerSocketTest::TearDownTestCase()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ServerSocketTest::SetUp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ServerSocketTest::TearDown()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: RegisterServerSocket
|
||||||
|
* FunctionPoints: create server socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function RegisterServerSocket can called twice, but the socket fd is same.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_001, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_001 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("ServerSocketTest");
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, serverSocket->GetSocketFd());
|
||||||
|
EXPECT_EQ(0, serverSocket->RegisterServerSocket());
|
||||||
|
int32_t socketFd = serverSocket->GetSocketFd();
|
||||||
|
EXPECT_LE(0, socketFd);
|
||||||
|
EXPECT_EQ(0, serverSocket->RegisterServerSocket());
|
||||||
|
EXPECT_EQ(socketFd, serverSocket->GetSocketFd());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_001 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: RegisterServerSocket
|
||||||
|
* FunctionPoints: create server socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function RegisterServerSocket create server socket fail with the empty socket name.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_002, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_002 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("");
|
||||||
|
EXPECT_EQ(-1, serverSocket->RegisterServerSocket());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_002 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: WaitForConnection
|
||||||
|
* FunctionPoints: accept socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function WaitForConnection accept fail when don't create server socket.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_003, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_003 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("ServerSocketTest");
|
||||||
|
EXPECT_EQ(-1, serverSocket->WaitForConnection(0));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_003 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: SaveConnection & VerifyConnection & CloseConnection
|
||||||
|
* FunctionPoints: connect fd
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the connect fd which be saved or not saved, then close the saved connect fd and verify them.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_004, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_004 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("ServerSocketTest");
|
||||||
|
int32_t connectFd1 = 111;
|
||||||
|
int32_t connectFd2 = 222;
|
||||||
|
int32_t connectFd3 = 333;
|
||||||
|
|
||||||
|
serverSocket->SaveConnection(connectFd1);
|
||||||
|
serverSocket->SaveConnection(connectFd2);
|
||||||
|
EXPECT_EQ(0, serverSocket->VerifyConnection(connectFd1));
|
||||||
|
EXPECT_EQ(0, serverSocket->VerifyConnection(connectFd2));
|
||||||
|
EXPECT_EQ(-1, serverSocket->VerifyConnection(connectFd3));
|
||||||
|
serverSocket->CloseConnection(connectFd2);
|
||||||
|
EXPECT_EQ(-1, serverSocket->VerifyConnection(connectFd2));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_004 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: CloseServerMonitor
|
||||||
|
* FunctionPoints: close the server socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function CloseServerMonitor which can close the server socket which has created
|
||||||
|
* successfully.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_005, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_005 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("ServerSocketTest");
|
||||||
|
|
||||||
|
EXPECT_EQ(0, serverSocket->RegisterServerSocket());
|
||||||
|
EXPECT_LE(0, serverSocket->GetSocketFd());
|
||||||
|
serverSocket->CloseServerMonitor();
|
||||||
|
EXPECT_EQ(-1, serverSocket->GetSocketFd());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_005 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: BindSocket
|
||||||
|
* FunctionPoints: bind the server socket
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the linux function bind which bind the invalid socket fd.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_006, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_006 start";
|
||||||
|
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>("ServerSocketTest");
|
||||||
|
EXPECT_EQ(-1, serverSocket->BindSocket(1));
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_006 end";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature: AppSpawn
|
||||||
|
* Function: ServerSocket
|
||||||
|
* SubFunction: RegisterServerSocket
|
||||||
|
* FunctionPoints: bind socket fail
|
||||||
|
* EnvConditions: mobile that can run ohos test framework
|
||||||
|
* CaseDescription: Verify the function RegisterServerSocket BindSocket fail and close the socket fd.
|
||||||
|
*/
|
||||||
|
HWTEST(ServerSocketTest, Server_Socket_007, TestSize.Level0)
|
||||||
|
{
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_007 start";
|
||||||
|
|
||||||
|
std::string invalidSocketName =
|
||||||
|
"InvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalid"
|
||||||
|
"InvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalidInvalid";
|
||||||
|
std::unique_ptr<ServerSocket> serverSocket = std::make_unique<ServerSocket>(invalidSocketName.c_str());
|
||||||
|
|
||||||
|
EXPECT_EQ(-1, serverSocket->RegisterServerSocket());
|
||||||
|
EXPECT_EQ(-1, serverSocket->GetSocketFd());
|
||||||
|
|
||||||
|
GTEST_LOG_(INFO) << "Server_Socket_007 end";
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user