1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "snapshot/mac/system_snapshot_mac.h"
16
17 #include <sys/time.h>
18
19 #include <string>
20
21 #include "build/build_config.h"
22 #include "gtest/gtest.h"
23 #include "snapshot/mac/process_reader_mac.h"
24 #include "test/errors.h"
25 #include "util/mac/mac_util.h"
26
27 namespace crashpad {
28 namespace test {
29 namespace {
30
31 // SystemSnapshotMac objects would be cumbersome to construct in each test that
32 // requires one, because of the repetitive and mechanical work necessary to set
33 // up a ProcessReaderMac and timeval, along with the checks to verify that these
34 // operations succeed. This test fixture class handles the initialization work
35 // so that individual tests don’t have to.
36 class SystemSnapshotMacTest : public testing::Test {
37 public:
SystemSnapshotMacTest()38 SystemSnapshotMacTest()
39 : Test(),
40 process_reader_(),
41 snapshot_time_(),
42 system_snapshot_() {
43 }
44
system_snapshot() const45 const internal::SystemSnapshotMac& system_snapshot() const {
46 return system_snapshot_;
47 }
48
49 // testing::Test:
SetUp()50 void SetUp() override {
51 ASSERT_TRUE(process_reader_.Initialize(mach_task_self()));
52 ASSERT_EQ(gettimeofday(&snapshot_time_, nullptr), 0)
53 << ErrnoMessage("gettimeofday");
54 system_snapshot_.Initialize(&process_reader_, &snapshot_time_);
55 }
56
57 private:
58 ProcessReaderMac process_reader_;
59 timeval snapshot_time_;
60 internal::SystemSnapshotMac system_snapshot_;
61
62 DISALLOW_COPY_AND_ASSIGN(SystemSnapshotMacTest);
63 };
64
TEST_F(SystemSnapshotMacTest,GetCPUArchitecture)65 TEST_F(SystemSnapshotMacTest, GetCPUArchitecture) {
66 CPUArchitecture cpu_architecture = system_snapshot().GetCPUArchitecture();
67
68 #if defined(ARCH_CPU_X86)
69 EXPECT_EQ(cpu_architecture, kCPUArchitectureX86);
70 #elif defined(ARCH_CPU_X86_64)
71 EXPECT_EQ(cpu_architecture, kCPUArchitectureX86_64);
72 #elif defined(ARCH_CPU_ARM64)
73 EXPECT_EQ(cpu_architecture, kCPUArchitectureARM64);
74 #else
75 #error port to your architecture
76 #endif
77 }
78
TEST_F(SystemSnapshotMacTest,CPUCount)79 TEST_F(SystemSnapshotMacTest, CPUCount) {
80 EXPECT_GE(system_snapshot().CPUCount(), 1);
81 }
82
TEST_F(SystemSnapshotMacTest,CPUVendor)83 TEST_F(SystemSnapshotMacTest, CPUVendor) {
84 std::string cpu_vendor = system_snapshot().CPUVendor();
85
86 #if defined(ARCH_CPU_X86_FAMILY)
87 // Apple has only shipped Intel x86-family CPUs, but here’s a small nod to the
88 // “Hackintosh” crowd.
89 if (cpu_vendor != "GenuineIntel" && cpu_vendor != "AuthenticAMD") {
90 FAIL() << "cpu_vendor " << cpu_vendor;
91 }
92 #elif defined(ARCH_CPU_ARM64)
93 EXPECT_EQ(cpu_vendor, "Apple processor");
94 #else
95 #error port to your architecture
96 #endif
97 }
98
99 #if defined(ARCH_CPU_X86_FAMILY)
100
TEST_F(SystemSnapshotMacTest,CPUX86SupportsDAZ)101 TEST_F(SystemSnapshotMacTest, CPUX86SupportsDAZ) {
102 // All x86-family CPUs that Apple is known to have shipped should support DAZ.
103 EXPECT_TRUE(system_snapshot().CPUX86SupportsDAZ());
104 }
105
106 #endif
107
TEST_F(SystemSnapshotMacTest,GetOperatingSystem)108 TEST_F(SystemSnapshotMacTest, GetOperatingSystem) {
109 EXPECT_EQ(system_snapshot().GetOperatingSystem(),
110 SystemSnapshot::kOperatingSystemMacOSX);
111 }
112
TEST_F(SystemSnapshotMacTest,OSVersion)113 TEST_F(SystemSnapshotMacTest, OSVersion) {
114 int major;
115 int minor;
116 int bugfix;
117 std::string build;
118 system_snapshot().OSVersion(&major, &minor, &bugfix, &build);
119
120 const int macos_version_number = MacOSVersionNumber();
121 EXPECT_EQ(major * 1'00'00 + minor * 1'00 +
122 (macos_version_number >= 10'13'04 ? bugfix : 0),
123 macos_version_number);
124 EXPECT_FALSE(build.empty());
125 }
126
TEST_F(SystemSnapshotMacTest,OSVersionFull)127 TEST_F(SystemSnapshotMacTest, OSVersionFull) {
128 EXPECT_FALSE(system_snapshot().OSVersionFull().empty());
129 }
130
TEST_F(SystemSnapshotMacTest,MachineDescription)131 TEST_F(SystemSnapshotMacTest, MachineDescription) {
132 EXPECT_FALSE(system_snapshot().MachineDescription().empty());
133 }
134
TEST_F(SystemSnapshotMacTest,NXEnabled)135 TEST_F(SystemSnapshotMacTest, NXEnabled) {
136 // Assume NX will always be enabled, as it was always enabled by default on
137 // all supported versions of macOS.
138 EXPECT_TRUE(system_snapshot().NXEnabled());
139 }
140
141 } // namespace
142 } // namespace test
143 } // namespace crashpad
144