1 //========- unittests/Support/Host.cpp - Host.cpp tests --------------========//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/Host.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/Triple.h"
12 #include "llvm/Support/FileSystem.h"
13 #include "llvm/Support/Path.h"
14 #include "llvm/Support/Program.h"
16 #include "gtest/gtest.h"
18 #define ASSERT_NO_ERROR(x) \
19 if (std::error_code ASSERT_NO_ERROR_ec = x) { \
20 SmallString<128> MessageStorage; \
21 raw_svector_ostream Message(MessageStorage); \
22 Message << #x ": did not return errc::success.\n" \
23 << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
24 << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
25 GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
31 class HostTest
: public testing::Test
{
35 bool isSupportedArchAndOS() {
36 // Initially this is only testing detection of the number of
37 // physical cores, which is currently only supported/tested for
38 // x86_64 Linux and Darwin.
39 return (Host
.getArch() == Triple::x86_64
&&
40 (Host
.isOSDarwin() || Host
.getOS() == Triple::Linux
));
43 HostTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
46 TEST_F(HostTest
, NumPhysicalCores
) {
47 int Num
= sys::getHostNumPhysicalCores();
49 if (isSupportedArchAndOS())
55 TEST(getLinuxHostCPUName
, ARM
) {
56 StringRef CortexA9ProcCpuinfo
= R
"(
58 model name : ARMv7 Processor rev 10 (v7l)
60 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
61 CPU implementer : 0x41
68 model name : ARMv7 Processor rev 10 (v7l)
70 Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
71 CPU implementer : 0x41
77 Hardware : Generic OMAP4 (Flattened Device Tree)
79 Serial : 0000000000000000
82 EXPECT_EQ(sys::detail::getHostCPUNameForARM(CortexA9ProcCpuinfo
),
84 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
87 // Verify that both CPU implementer and CPU part are checked:
88 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
91 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
96 TEST(getLinuxHostCPUName
, AArch64
) {
97 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
100 // Verify that both CPU implementer and CPU part are checked:
101 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
104 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
107 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
110 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
113 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
116 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
120 // MSM8992/4 weirdness
121 StringRef MSM8992ProcCpuInfo
= R
"(
122 Processor : AArch64 Processor rev 3 (aarch64)
129 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
130 CPU implementer : 0x41
136 Hardware : Qualcomm Technologies, Inc MSM8992
139 EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo
),
142 // Exynos big.LITTLE weirdness
143 const std::string ExynosProcCpuInfo
= R
"(
145 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
146 CPU implementer : 0x41
152 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
153 CPU implementer : 0x53
157 // Verify default for Exynos.
158 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo
+
159 "CPU variant : 0xc\n"
163 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo
+
164 "CPU variant : 0x1\n"
168 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo
+
169 "CPU variant : 0x4\n"
173 const std::string ThunderX2T99ProcCpuInfo
= R
"(
176 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
177 CPU implementer : 0x43
183 // Verify different versions of ThunderX2T99.
184 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
185 "CPU implementer : 0x42\n"
189 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
190 "CPU implementer : 0x42\n"
191 "CPU part : 0x0516"),
194 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
195 "CPU implementer : 0x43\n"
199 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
200 "CPU implementer : 0x43\n"
201 "CPU part : 0x0516"),
204 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
205 "CPU implementer : 0x42\n"
209 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
210 "CPU implementer : 0x42\n"
214 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
215 "CPU implementer : 0x43\n"
219 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo
+
220 "CPU implementer : 0x43\n"
224 // Verify ThunderXT88.
225 const std::string ThunderXT88ProcCpuInfo
= R
"(
228 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
229 CPU implementer : 0x43
235 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo
+
236 "CPU implementer : 0x43\n"
240 EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo
+
241 "CPU implementer : 0x43\n"
245 // Verify HiSilicon processors.
246 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n"
251 #if defined(__APPLE__)
252 TEST_F(HostTest
, getMacOSHostVersion
) {
253 using namespace llvm::sys
;
254 llvm::Triple
HostTriple(getProcessTriple());
255 if (!HostTriple
.isMacOSX())
258 SmallString
<128> TestDirectory
;
259 ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory
));
260 SmallString
<128> OutputFile(TestDirectory
);
261 path::append(OutputFile
, "out");
263 const char *SwVersPath
= "/usr/bin/sw_vers";
264 StringRef argv
[] = {SwVersPath
, "-productVersion"};
265 StringRef OutputPath
= OutputFile
.str();
266 const Optional
<StringRef
> Redirects
[] = {/*STDIN=*/None
,
267 /*STDOUT=*/OutputPath
,
269 int RetCode
= ExecuteAndWait(SwVersPath
, argv
, /*env=*/llvm::None
, Redirects
);
270 ASSERT_EQ(0, RetCode
);
273 ASSERT_NO_ERROR(fs::openFileForRead(OutputPath
, FD
));
274 off_t Size
= ::lseek(FD
, 0, SEEK_END
);
276 ::lseek(FD
, 0, SEEK_SET
);
277 std::unique_ptr
<char[]> Buffer
= llvm::make_unique
<char[]>(Size
);
278 ASSERT_EQ(::read(FD
, Buffer
.get(), Size
), Size
);
281 // Ensure that the two versions match.
282 StringRef
SystemVersion(Buffer
.get(), Size
);
283 unsigned SystemMajor
, SystemMinor
, SystemMicro
;
284 ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersion
))
285 .getMacOSXVersion(SystemMajor
, SystemMinor
, SystemMicro
),
287 unsigned HostMajor
, HostMinor
, HostMicro
;
288 ASSERT_EQ(HostTriple
.getMacOSXVersion(HostMajor
, HostMinor
, HostMicro
), true);
290 // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
292 ASSERT_EQ(std::tie(SystemMajor
, SystemMinor
), std::tie(HostMajor
, HostMinor
));
294 ASSERT_NO_ERROR(fs::remove(OutputPath
));
295 ASSERT_NO_ERROR(fs::remove(TestDirectory
.str()));