update OpenHarmony 2.0 Canary

This commit is contained in:
mamingshuai 2021-06-02 00:04:01 +08:00
parent 7e65880a39
commit 2da052f1e2
42 changed files with 5176 additions and 73 deletions

15
.gitattributes vendored Normal file
View 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
View 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
View 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
View 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:
" == &gt;
& == &gt;
' == &gt;
< == &gt;
> == &gt;
-->
<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>

View File

@ -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/)

View File

@ -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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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

View 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
View 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" ]
}

View 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

View 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

View 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

View 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

View 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

View 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
View 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" ]
}

View 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 &params)
{
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 &params)
{
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 &params)
{
// 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 &params)
{
// 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 &params)
{
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");
}

View 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" ]
}

View File

@ -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";
}

View 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",
]
}

View File

@ -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";
}

View File

@ -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";
}

View 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" ]
}

View 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";
}

View 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" ]
}

View 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";
}

View 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" ]
}

View 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";
}