OLD | NEW |
(Empty) | |
| 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 "util/mac/mac_util.h" |
| 16 |
| 17 #import <Foundation/Foundation.h> |
| 18 #include <stdlib.h> |
| 19 |
| 20 #include <string> |
| 21 |
| 22 #include "base/mac/scoped_nsobject.h" |
| 23 #include "base/strings/stringprintf.h" |
| 24 #include "gtest/gtest.h" |
| 25 |
| 26 #ifdef __GLIBCXX__ |
| 27 // When C++ exceptions are disabled, libstdc++ from GCC 4.2 defines |try| and |
| 28 // |catch| so as to allow exception-expecting C++ code to build properly when |
| 29 // language support for exceptions is not present. These macros interfere with |
| 30 // the use of |@try| and |@catch| in Objective-C files such as this one. |
| 31 // Undefine these macros here, after everything has been #included, since there |
| 32 // will be no C++ uses and only Objective-C uses from this point on. |
| 33 #undef try |
| 34 #undef catch |
| 35 #endif |
| 36 |
| 37 namespace { |
| 38 |
| 39 using namespace crashpad; |
| 40 |
| 41 // Runs /usr/bin/sw_vers with a single argument, |argument|, and places the |
| 42 // command’s standard output into |output| after stripping the trailing newline. |
| 43 // Fatal gtest assertions report tool failures, which the caller should check |
| 44 // for with testing::Test::HasFatalFailure(). |
| 45 void SwVers(NSString* argument, std::string* output) { |
| 46 @autoreleasepool { |
| 47 base::scoped_nsobject<NSPipe> pipe([[NSPipe alloc] init]); |
| 48 base::scoped_nsobject<NSTask> task([[NSTask alloc] init]); |
| 49 [task setStandardOutput:pipe]; |
| 50 [task setLaunchPath:@"/usr/bin/sw_vers"]; |
| 51 [task setArguments:@[ argument ]]; |
| 52 |
| 53 @try { |
| 54 [task launch]; |
| 55 } |
| 56 @catch (NSException* exception) { |
| 57 FAIL() << [[exception name] UTF8String] << ": " |
| 58 << [[exception reason] UTF8String]; |
| 59 } |
| 60 |
| 61 NSData* data = [[pipe fileHandleForReading] readDataToEndOfFile]; |
| 62 [task waitUntilExit]; |
| 63 |
| 64 ASSERT_EQ(NSTaskTerminationReasonExit, [task terminationReason]); |
| 65 ASSERT_EQ(EXIT_SUCCESS, [task terminationStatus]); |
| 66 |
| 67 output->assign(reinterpret_cast<const char*>([data bytes]), [data length]); |
| 68 |
| 69 EXPECT_EQ('\n', output->at(output->size() - 1)); |
| 70 output->resize(output->size() - 1); |
| 71 } |
| 72 } |
| 73 |
| 74 TEST(MacUtil, MacOSXVersion) { |
| 75 int major; |
| 76 int minor; |
| 77 int bugfix; |
| 78 std::string build; |
| 79 bool server; |
| 80 std::string version_string; |
| 81 ASSERT_TRUE( |
| 82 MacOSXVersion(&major, &minor, &bugfix, &build, &server, &version_string)); |
| 83 |
| 84 std::string version; |
| 85 if (bugfix) { |
| 86 version = base::StringPrintf("%d.%d.%d", major, minor, bugfix); |
| 87 } else { |
| 88 // 10.x.0 releases report their version string as simply 10.x. |
| 89 version = base::StringPrintf("%d.%d", major, minor); |
| 90 } |
| 91 |
| 92 std::string expected_product_version; |
| 93 SwVers(@"-productVersion", &expected_product_version); |
| 94 if (Test::HasFatalFailure()) { |
| 95 return; |
| 96 } |
| 97 |
| 98 EXPECT_EQ(expected_product_version, version); |
| 99 |
| 100 std::string expected_build_version; |
| 101 SwVers(@"-buildVersion", &expected_build_version); |
| 102 if (Test::HasFatalFailure()) { |
| 103 return; |
| 104 } |
| 105 |
| 106 EXPECT_EQ(expected_build_version, build); |
| 107 |
| 108 std::string expected_product_name; |
| 109 SwVers(@"-productName", &expected_product_name); |
| 110 if (Test::HasFatalFailure()) { |
| 111 return; |
| 112 } |
| 113 |
| 114 // Look for a space after the product name in the complete version string. |
| 115 expected_product_name += ' '; |
| 116 EXPECT_EQ(0u, version_string.find(expected_product_name)); |
| 117 } |
| 118 |
| 119 TEST(MacUtil, MacOSXMinorVersion) { |
| 120 // Make sure that MacOSXMinorVersion() and MacOSXVersion() agree. The two have |
| 121 // their own distinct implementations, and the latter was checked against |
| 122 // sw_vers above. |
| 123 int major; |
| 124 int minor; |
| 125 int bugfix; |
| 126 std::string build; |
| 127 bool server; |
| 128 std::string version_string; |
| 129 ASSERT_TRUE( |
| 130 MacOSXVersion(&major, &minor, &bugfix, &build, &server, &version_string)); |
| 131 |
| 132 EXPECT_EQ(minor, MacOSXMinorVersion()); |
| 133 } |
| 134 |
| 135 TEST(MacUtil, MacModelAndBoard) { |
| 136 // There’s not much that can be done to test these, so just make sure they’re |
| 137 // not empty. The model could be compared against the parsed output of |
| 138 // “system_profiler SPHardwareDataType”, but the board doesn’t show up |
| 139 // anywhere other than the I/O Registry, and that’s exactly how |
| 140 // MacModelAndBoard() gets the data, so it wouldn’t be a very useful test. |
| 141 std::string model; |
| 142 std::string board; |
| 143 MacModelAndBoard(&model, &board); |
| 144 |
| 145 EXPECT_FALSE(model.empty()); |
| 146 EXPECT_FALSE(board.empty()); |
| 147 } |
| 148 |
| 149 } // namespace |
OLD | NEW |