xref: /llvm-project/lldb/unittests/Host/linux/HostTest.cpp (revision 8f74725731bf431fb97929e1dd962e9a0db20865)
1 //===-- HostTest.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/Host.h"
10 #include "lldb/Host/FileSystem.h"
11 #include "lldb/Host/HostInfo.h"
12 #include "lldb/Utility/ProcessInfo.h"
13 #include "gtest/gtest.h"
14 
15 #include <cerrno>
16 #include <sys/resource.h>
17 
18 using namespace lldb_private;
19 
20 namespace {
21 class HostTest : public testing::Test {
22 public:
SetUpTestCase()23   static void SetUpTestCase() {
24     FileSystem::Initialize();
25     HostInfo::Initialize();
26   }
TearDownTestCase()27   static void TearDownTestCase() {
28     HostInfo::Terminate();
29     FileSystem::Terminate();
30   }
31 };
32 } // namespace
33 
TEST_F(HostTest,GetProcessInfo)34 TEST_F(HostTest, GetProcessInfo) {
35   llvm::Triple triple = HostInfo::GetTargetTriple();
36 
37   ASSERT_TRUE(
38       (triple.getOS() == llvm::Triple::OSType::Linux) ||
39       (triple.hasEnvironment() &&
40        triple.getEnvironment() == llvm::Triple::EnvironmentType::Android));
41 
42   ProcessInstanceInfo Info;
43   ASSERT_FALSE(Host::GetProcessInfo(0, Info));
44 
45   ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
46 
47   ASSERT_TRUE(Info.ProcessIDIsValid());
48   EXPECT_EQ(lldb::pid_t(getpid()), Info.GetProcessID());
49 
50   ASSERT_TRUE(Info.ParentProcessIDIsValid());
51   EXPECT_EQ(lldb::pid_t(getppid()), Info.GetParentProcessID());
52 
53   ASSERT_TRUE(Info.ProcessGroupIDIsValid());
54   EXPECT_EQ(lldb::pid_t(getpgrp()), Info.GetProcessGroupID());
55 
56   ASSERT_TRUE(Info.ProcessSessionIDIsValid());
57   EXPECT_EQ(lldb::pid_t(getsid(getpid())), Info.GetProcessSessionID());
58 
59   ASSERT_TRUE(Info.EffectiveUserIDIsValid());
60   EXPECT_EQ(geteuid(), Info.GetEffectiveUserID());
61 
62   ASSERT_TRUE(Info.EffectiveGroupIDIsValid());
63   EXPECT_EQ(getegid(), Info.GetEffectiveGroupID());
64 
65   ASSERT_TRUE(Info.UserIDIsValid());
66   EXPECT_EQ(geteuid(), Info.GetUserID());
67 
68   ASSERT_TRUE(Info.GroupIDIsValid());
69   EXPECT_EQ(getegid(), Info.GetGroupID());
70 
71   EXPECT_TRUE(Info.GetArchitecture().IsValid());
72   EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault),
73             Info.GetArchitecture());
74   // Test timings
75   // In some sense this is a pretty trivial test. What it is trying to
76   // accomplish is just to validate that these values are never decreasing
77   // which would be unambiguously wrong. We can not reliably show them
78   // to be always increasing because the microsecond granularity means that,
79   // with hardware variations the number of loop iterations need to always
80   // be increasing for faster and faster machines.
81   ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
82   ProcessInstanceInfo::timespec user_time = Info.GetUserTime();
83   static volatile unsigned u = 0;
84   for (unsigned i = 0; i < 10'000'000; i++) {
85     u += i;
86   }
87   ASSERT_TRUE(u > 0);
88   ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
89   ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime();
90   ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec ||
91               user_time.tv_usec <= next_user_time.tv_usec);
92 
93   struct rlimit rlim;
94   EXPECT_EQ(getrlimit(RLIMIT_NICE, &rlim), 0);
95   // getpriority can return -1 so we zero errno first
96   errno = 0;
97   int prio = getpriority(PRIO_PROCESS, PRIO_PROCESS);
98   ASSERT_TRUE((prio < 0 && errno == 0) || prio >= 0);
99   ASSERT_EQ(Info.GetPriorityValue(), prio);
100   // If we can't raise our nice level then this test can't be performed.
101   int max_incr = PRIO_MAX - rlim.rlim_cur;
102   if (max_incr < prio) {
103     EXPECT_EQ(setpriority(PRIO_PROCESS, PRIO_PROCESS, prio - 1), 0);
104     ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
105     ASSERT_TRUE(Info.GetPriorityValue().has_value());
106     ASSERT_EQ(Info.GetPriorityValue().value(), prio - 1);
107     EXPECT_EQ(setpriority(PRIO_PROCESS, PRIO_PROCESS, prio), 0);
108   }
109   ASSERT_TRUE(Info.IsZombie().has_value());
110   ASSERT_FALSE(Info.IsZombie().value());
111 }
112