Home | History | Annotate | Download | only in libprocinfo
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <procinfo/process.h>
     18 
     19 #include <fcntl.h>
     20 #include <stdlib.h>
     21 #include <sys/types.h>
     22 #include <unistd.h>
     23 
     24 #include <chrono>
     25 #include <set>
     26 #include <thread>
     27 #include <vector>
     28 
     29 #include <gtest/gtest.h>
     30 
     31 #include <android-base/stringprintf.h>
     32 
     33 using namespace std::chrono_literals;
     34 
     35 #if !defined(__BIONIC__)
     36 #include <syscall.h>
     37 static pid_t gettid() {
     38   return syscall(__NR_gettid);
     39 }
     40 #endif
     41 
     42 TEST(process_info, process_info_smoke) {
     43   android::procinfo::ProcessInfo self;
     44   ASSERT_TRUE(android::procinfo::GetProcessInfo(gettid(), &self));
     45   ASSERT_EQ(gettid(), self.tid);
     46   ASSERT_EQ(getpid(), self.pid);
     47   ASSERT_EQ(getppid(), self.ppid);
     48   ASSERT_EQ(getuid(), self.uid);
     49   ASSERT_EQ(getgid(), self.gid);
     50 }
     51 
     52 TEST(process_info, process_info_proc_pid_fd_smoke) {
     53   android::procinfo::ProcessInfo self;
     54   int fd = open(android::base::StringPrintf("/proc/%d", gettid()).c_str(), O_DIRECTORY | O_RDONLY);
     55   ASSERT_NE(-1, fd);
     56   ASSERT_TRUE(android::procinfo::GetProcessInfoFromProcPidFd(fd, &self));
     57 
     58   // Process name is capped at 15 bytes.
     59   ASSERT_EQ("libprocinfo_tes", self.name);
     60   ASSERT_EQ(gettid(), self.tid);
     61   ASSERT_EQ(getpid(), self.pid);
     62   ASSERT_EQ(getppid(), self.ppid);
     63   ASSERT_EQ(getuid(), self.uid);
     64   ASSERT_EQ(getgid(), self.gid);
     65   close(fd);
     66 }
     67 
     68 TEST(process_info, process_tids_smoke) {
     69   pid_t main_tid = gettid();
     70   std::thread([main_tid]() {
     71     pid_t thread_tid = gettid();
     72 
     73     {
     74       std::vector<pid_t> vec;
     75       ASSERT_TRUE(android::procinfo::GetProcessTids(getpid(), &vec));
     76       ASSERT_EQ(1, std::count(vec.begin(), vec.end(), main_tid));
     77       ASSERT_EQ(1, std::count(vec.begin(), vec.end(), thread_tid));
     78     }
     79 
     80     {
     81       std::set<pid_t> set;
     82       ASSERT_TRUE(android::procinfo::GetProcessTids(getpid(), &set));
     83       ASSERT_EQ(1, std::count(set.begin(), set.end(), main_tid));
     84       ASSERT_EQ(1, std::count(set.begin(), set.end(), thread_tid));
     85     }
     86   }).join();
     87 }
     88 
     89 TEST(process_info, process_state) {
     90   int pipefd[2];
     91   ASSERT_EQ(0, pipe2(pipefd, O_CLOEXEC));
     92   pid_t forkpid = fork();
     93 
     94   ASSERT_NE(-1, forkpid);
     95   if (forkpid == 0) {
     96     close(pipefd[1]);
     97     char buf;
     98     TEMP_FAILURE_RETRY(read(pipefd[0], &buf, 1));
     99     _exit(0);
    100   }
    101 
    102   // Give the child some time to get to the read.
    103   std::this_thread::sleep_for(100ms);
    104 
    105   android::procinfo::ProcessInfo procinfo;
    106   ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo));
    107   ASSERT_EQ(android::procinfo::kProcessStateSleeping, procinfo.state);
    108 
    109   ASSERT_EQ(0, kill(forkpid, SIGKILL));
    110 
    111   // Give the kernel some time to kill the child.
    112   std::this_thread::sleep_for(100ms);
    113 
    114   ASSERT_TRUE(android::procinfo::GetProcessInfo(forkpid, &procinfo));
    115   ASSERT_EQ(android::procinfo::kProcessStateZombie, procinfo.state);
    116 
    117   ASSERT_EQ(forkpid, waitpid(forkpid, nullptr, 0));
    118 }
    119