157 lines
5.1 KiB
Plaintext
157 lines
5.1 KiB
Plaintext
|
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
|||
|
//
|
|||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
|
// you may not use this file except in compliance with the License.
|
|||
|
// You may obtain a copy of the License at
|
|||
|
//
|
|||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|||
|
//
|
|||
|
// Unless required by applicable law or agreed to in writing, software
|
|||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
|
// See the License for the specific language governing permissions and
|
|||
|
// limitations under the License.
|
|||
|
|
|||
|
#include "util/mac/mac_util.h"
|
|||
|
|
|||
|
#import <Foundation/Foundation.h>
|
|||
|
#include <stdlib.h>
|
|||
|
|
|||
|
#include <string>
|
|||
|
|
|||
|
#include "base/mac/scoped_nsobject.h"
|
|||
|
#include "base/strings/stringprintf.h"
|
|||
|
#include "gtest/gtest.h"
|
|||
|
|
|||
|
#ifdef __GLIBCXX__
|
|||
|
// When C++ exceptions are disabled, libstdc++ from GCC 4.2 defines |try| and
|
|||
|
// |catch| so as to allow exception-expecting C++ code to build properly when
|
|||
|
// language support for exceptions is not present. These macros interfere with
|
|||
|
// the use of |@try| and |@catch| in Objective-C files such as this one.
|
|||
|
// Undefine these macros here, after everything has been #included, since there
|
|||
|
// will be no C++ uses and only Objective-C uses from this point on.
|
|||
|
#undef try
|
|||
|
#undef catch
|
|||
|
#endif
|
|||
|
|
|||
|
namespace crashpad {
|
|||
|
namespace test {
|
|||
|
namespace {
|
|||
|
|
|||
|
// Runs /usr/bin/sw_vers with a single argument, |argument|, and places the
|
|||
|
// command’s standard output into |output| after stripping the trailing newline.
|
|||
|
// Fatal Google Test assertions report tool failures, which the caller should
|
|||
|
// check for with ASSERT_NO_FATAL_FAILURE() or testing::Test::HasFatalFailure().
|
|||
|
void SwVers(NSString* argument, std::string* output) {
|
|||
|
@autoreleasepool {
|
|||
|
base::scoped_nsobject<NSPipe> pipe([[NSPipe alloc] init]);
|
|||
|
base::scoped_nsobject<NSTask> task([[NSTask alloc] init]);
|
|||
|
[task setStandardOutput:pipe];
|
|||
|
[task setLaunchPath:@"/usr/bin/sw_vers"];
|
|||
|
[task setArguments:@[ argument ]];
|
|||
|
|
|||
|
@try {
|
|||
|
[task launch];
|
|||
|
}
|
|||
|
@catch (NSException* exception) {
|
|||
|
FAIL() << [[exception name] UTF8String] << ": "
|
|||
|
<< [[exception reason] UTF8String];
|
|||
|
}
|
|||
|
|
|||
|
NSData* data = [[pipe fileHandleForReading] readDataToEndOfFile];
|
|||
|
[task waitUntilExit];
|
|||
|
|
|||
|
ASSERT_EQ([task terminationReason], NSTaskTerminationReasonExit);
|
|||
|
ASSERT_EQ([task terminationStatus], EXIT_SUCCESS);
|
|||
|
|
|||
|
output->assign(reinterpret_cast<const char*>([data bytes]), [data length]);
|
|||
|
|
|||
|
EXPECT_EQ(output->at(output->size() - 1), '\n');
|
|||
|
output->resize(output->size() - 1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
TEST(MacUtil, MacOSVersionComponents) {
|
|||
|
int major;
|
|||
|
int minor;
|
|||
|
int bugfix;
|
|||
|
std::string build;
|
|||
|
bool server;
|
|||
|
std::string version_string;
|
|||
|
ASSERT_TRUE(MacOSVersionComponents(
|
|||
|
&major, &minor, &bugfix, &build, &server, &version_string));
|
|||
|
|
|||
|
EXPECT_GE(major, 10);
|
|||
|
EXPECT_LE(major, 99);
|
|||
|
EXPECT_GE(minor, 0);
|
|||
|
EXPECT_LE(minor, 99);
|
|||
|
EXPECT_GE(bugfix, 0);
|
|||
|
EXPECT_LE(bugfix, 99);
|
|||
|
|
|||
|
std::string version;
|
|||
|
if (bugfix) {
|
|||
|
version = base::StringPrintf("%d.%d.%d", major, minor, bugfix);
|
|||
|
} else {
|
|||
|
// 10.x.0 releases report their version string as simply 10.x.
|
|||
|
version = base::StringPrintf("%d.%d", major, minor);
|
|||
|
}
|
|||
|
|
|||
|
std::string expected_product_version;
|
|||
|
ASSERT_NO_FATAL_FAILURE(
|
|||
|
SwVers(@"-productVersion", &expected_product_version));
|
|||
|
|
|||
|
EXPECT_EQ(version, expected_product_version);
|
|||
|
|
|||
|
std::string expected_build_version;
|
|||
|
ASSERT_NO_FATAL_FAILURE(SwVers(@"-buildVersion", &expected_build_version));
|
|||
|
|
|||
|
EXPECT_EQ(build, expected_build_version);
|
|||
|
|
|||
|
std::string expected_product_name;
|
|||
|
ASSERT_NO_FATAL_FAILURE(SwVers(@"-productName", &expected_product_name));
|
|||
|
|
|||
|
// Look for a space after the product name in the complete version string.
|
|||
|
expected_product_name += ' ';
|
|||
|
EXPECT_EQ(version_string.find(expected_product_name), 0u);
|
|||
|
}
|
|||
|
|
|||
|
TEST(MacUtil, MacOSVersionNumber) {
|
|||
|
// Make sure that MacOSVersionNumber() and MacOSVersionComponents() agree. The
|
|||
|
// two have their own distinct implementations, and the latter was checked
|
|||
|
// against sw_vers above.
|
|||
|
int macos_version_number = MacOSVersionNumber();
|
|||
|
EXPECT_GE(macos_version_number, 10'00'00);
|
|||
|
EXPECT_LE(macos_version_number, 99'99'99);
|
|||
|
|
|||
|
int major;
|
|||
|
int minor;
|
|||
|
int bugfix;
|
|||
|
std::string build;
|
|||
|
bool server;
|
|||
|
std::string version_string;
|
|||
|
ASSERT_TRUE(MacOSVersionComponents(
|
|||
|
&major, &minor, &bugfix, &build, &server, &version_string));
|
|||
|
|
|||
|
EXPECT_EQ(macos_version_number,
|
|||
|
major * 1'00'00 + minor * 1'00 +
|
|||
|
(macos_version_number >= 10'13'04 ? bugfix : 0));
|
|||
|
}
|
|||
|
|
|||
|
TEST(MacUtil, MacModelAndBoard) {
|
|||
|
// There’s not much that can be done to test these, so just make sure they’re
|
|||
|
// not empty. The model could be compared against the parsed output of
|
|||
|
// “system_profiler SPHardwareDataType”, but the board doesn’t show up
|
|||
|
// anywhere other than the I/O Registry, and that’s exactly how
|
|||
|
// MacModelAndBoard() gets the data, so it wouldn’t be a very useful test.
|
|||
|
std::string model;
|
|||
|
std::string board;
|
|||
|
MacModelAndBoard(&model, &board);
|
|||
|
|
|||
|
EXPECT_FALSE(model.empty());
|
|||
|
EXPECT_FALSE(board.empty());
|
|||
|
}
|
|||
|
|
|||
|
} // namespace
|
|||
|
} // namespace test
|
|||
|
} // namespace crashpad
|