1f6603c60Sopenharmony_ci/* Copyright (C) 2022 Huawei Device Co., Ltd. 2f6603c60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 3f6603c60Sopenharmony_ci * you may not use this file except in compliance with the License. 4f6603c60Sopenharmony_ci * You may obtain a copy of the License at 5f6603c60Sopenharmony_ci * 6f6603c60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 7f6603c60Sopenharmony_ci * 8f6603c60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 9f6603c60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 10f6603c60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11f6603c60Sopenharmony_ci * See the License for the specific language governing permissions and 12f6603c60Sopenharmony_ci * limitations under the License. 13f6603c60Sopenharmony_ci */ 14f6603c60Sopenharmony_ci#include <iostream> 15f6603c60Sopenharmony_ci#include <cstdlib> 16f6603c60Sopenharmony_ci#include <cstring> 17f6603c60Sopenharmony_ci#include <cerrno> 18f6603c60Sopenharmony_ci#include <ctime> 19f6603c60Sopenharmony_ci#include <cstdio> 20f6603c60Sopenharmony_ci#include <vector> 21f6603c60Sopenharmony_ci#include <csignal> 22f6603c60Sopenharmony_ci#include <unistd.h> 23f6603c60Sopenharmony_ci#include <dirent.h> 24f6603c60Sopenharmony_ci#include <sys/types.h> 25f6603c60Sopenharmony_ci#include <sys/wait.h> 26f6603c60Sopenharmony_ci#include <sys/time.h> 27f6603c60Sopenharmony_ci#include <sys/resource.h> 28f6603c60Sopenharmony_ci 29f6603c60Sopenharmony_ci#include "gtest/gtest.h" 30f6603c60Sopenharmony_ci#include "runtest.h" 31f6603c60Sopenharmony_ci 32f6603c60Sopenharmony_ciusing namespace std; 33f6603c60Sopenharmony_ciusing namespace testing::ext; 34f6603c60Sopenharmony_ciusing namespace testing; 35f6603c60Sopenharmony_cinamespace OHOS { 36f6603c60Sopenharmony_ciclass Toolchaintest : public ::testing::TestWithParam<string> {}; 37f6603c60Sopenharmony_ci 38f6603c60Sopenharmony_cistatic string g_filepath = "/data/local/tmp/libc-test"; 39f6603c60Sopenharmony_cistatic vector<std::string> temp = Runtest::GetFileNames(g_filepath); 40f6603c60Sopenharmony_ci 41f6603c60Sopenharmony_civolatile int g_tStatus = 0; 42f6603c60Sopenharmony_ci 43f6603c60Sopenharmony_cistatic void Handler(int sig) 44f6603c60Sopenharmony_ci{ 45f6603c60Sopenharmony_ci} 46f6603c60Sopenharmony_ci 47f6603c60Sopenharmony_cistatic int Start(const char *argvs) 48f6603c60Sopenharmony_ci{ 49f6603c60Sopenharmony_ci int pid, spaceSize = 100 * 1024; 50f6603c60Sopenharmony_ci // Create a child process 51f6603c60Sopenharmony_ci // Set the process stack space 52f6603c60Sopenharmony_ci pid = fork(); 53f6603c60Sopenharmony_ci if (pid == 0) { 54f6603c60Sopenharmony_ci Runtest::TSetrlim(RLIMIT_STACK, spaceSize); 55f6603c60Sopenharmony_ci // Overloading the subprocess space 56f6603c60Sopenharmony_ci int exe = execl(argvs, "strptime", nullptr); 57f6603c60Sopenharmony_ci printf("exe:%d %s exec failed: %s\n", exe, argvs, strerror(errno)); 58f6603c60Sopenharmony_ci exit(1); 59f6603c60Sopenharmony_ci } 60f6603c60Sopenharmony_ci return pid; 61f6603c60Sopenharmony_ci} 62f6603c60Sopenharmony_ci 63f6603c60Sopenharmony_cistatic int RunTests(const char *argvs) 64f6603c60Sopenharmony_ci{ 65f6603c60Sopenharmony_ci int timeoutsec = 10, timeout = 0; 66f6603c60Sopenharmony_ci int status, pid; 67f6603c60Sopenharmony_ci sigset_t set; 68f6603c60Sopenharmony_ci void (*retfunc)(int); 69f6603c60Sopenharmony_ci // signal set 70f6603c60Sopenharmony_ci sigemptyset(&set); 71f6603c60Sopenharmony_ci sigaddset(&set, SIGCHLD); 72f6603c60Sopenharmony_ci sigprocmask(SIG_BLOCK, &set, nullptr); 73f6603c60Sopenharmony_ci retfunc = signal(SIGCHLD, Handler); 74f6603c60Sopenharmony_ci if (retfunc == SIG_ERR) { 75f6603c60Sopenharmony_ci printf("signal triggering failed:%s\n", strerror(errno)); 76f6603c60Sopenharmony_ci } 77f6603c60Sopenharmony_ci pid = Start(argvs); 78f6603c60Sopenharmony_ci // The function system call failed 79f6603c60Sopenharmony_ci if (pid == -1) { 80f6603c60Sopenharmony_ci printf("%s fork failed: %s\n", argvs, strerror(errno)); 81f6603c60Sopenharmony_ci printf("FAIL %s [internal]\n", argvs); 82f6603c60Sopenharmony_ci return -1; 83f6603c60Sopenharmony_ci } 84f6603c60Sopenharmony_ci struct timespec tp; 85f6603c60Sopenharmony_ci // Maximum blocking time 86f6603c60Sopenharmony_ci tp.tv_sec = timeoutsec; 87f6603c60Sopenharmony_ci tp.tv_nsec = 0; 88f6603c60Sopenharmony_ci if (sigtimedwait(&set, nullptr, &tp) == -1) { 89f6603c60Sopenharmony_ci // Call it again 90f6603c60Sopenharmony_ci if (errno == EAGAIN) { 91f6603c60Sopenharmony_ci timeout = 1; 92f6603c60Sopenharmony_ci } else { 93f6603c60Sopenharmony_ci printf("%s sigtimedwait failed: %s\n", argvs, strerror(errno)); 94f6603c60Sopenharmony_ci } 95f6603c60Sopenharmony_ci if (kill(pid, SIGKILL) == -1) { 96f6603c60Sopenharmony_ci printf("%s kill failed: %s\n", argvs, strerror(errno)); 97f6603c60Sopenharmony_ci } 98f6603c60Sopenharmony_ci } 99f6603c60Sopenharmony_ci // Waiting for the process to stop 100f6603c60Sopenharmony_ci if (waitpid(pid, &status, 0) != pid) { 101f6603c60Sopenharmony_ci printf("%s waitpid failed: %s\n", argvs, strerror(errno)); 102f6603c60Sopenharmony_ci printf("FAIL %s [internal]\n", argvs); 103f6603c60Sopenharmony_ci return -1; 104f6603c60Sopenharmony_ci } 105f6603c60Sopenharmony_ci // Process state 106f6603c60Sopenharmony_ci if (WIFEXITED(status)) { // The right exit 107f6603c60Sopenharmony_ci if (WEXITSTATUS(status) == 0) { // operate successfully 108f6603c60Sopenharmony_ci return g_tStatus; 109f6603c60Sopenharmony_ci } 110f6603c60Sopenharmony_ci printf("FAIL %s [status %d]\n", argvs, WEXITSTATUS(status)); 111f6603c60Sopenharmony_ci } else if (timeout) { 112f6603c60Sopenharmony_ci printf("FAIL %s [timed out]\n", argvs); 113f6603c60Sopenharmony_ci } else if (WIFSIGNALED(status)) { 114f6603c60Sopenharmony_ci printf("FAIL %s [signal %s]\n", argvs, strsignal(WTERMSIG(status))); 115f6603c60Sopenharmony_ci } else { 116f6603c60Sopenharmony_ci printf("FAIL %s [unknown]\n", argvs); 117f6603c60Sopenharmony_ci } 118f6603c60Sopenharmony_ci return 1; 119f6603c60Sopenharmony_ci} 120f6603c60Sopenharmony_ci 121f6603c60Sopenharmony_ci 122f6603c60Sopenharmony_ci/** 123f6603c60Sopenharmony_ci * @tc.name : Toolchaintest.LibcTest 124f6603c60Sopenharmony_ci * @tc.desc : start test 125f6603c60Sopenharmony_ci * @tc.level : Level 3 126f6603c60Sopenharmony_ci */ 127f6603c60Sopenharmony_ciHWTEST_P(Toolchaintest, LibcTest, Function | MediumTest | Level3) 128f6603c60Sopenharmony_ci{ 129f6603c60Sopenharmony_ci int ret; 130f6603c60Sopenharmony_ci string testName = GetParam(); 131f6603c60Sopenharmony_ci ret = RunTests(testName.c_str()); 132f6603c60Sopenharmony_ci if (ret == 0) { 133f6603c60Sopenharmony_ci EXPECT_EQ(0, ret) << "test " << testName << " succeed" << endl; 134f6603c60Sopenharmony_ci } else { 135f6603c60Sopenharmony_ci EXPECT_EQ(1, ret) << "test " << testName << " failed" << endl; 136f6603c60Sopenharmony_ci EXPECT_EQ(-1, ret) << "test " << testName << " failed" << endl; 137f6603c60Sopenharmony_ci } 138f6603c60Sopenharmony_ci} 139f6603c60Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(libcTest, Toolchaintest, testing::ValuesIn(temp.begin(), temp.end())); 140f6603c60Sopenharmony_ci} // namespace OHOS 141