blob: 2f0e430435183b7fbb953d7b9fcee737d1f00551 [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "debugd/src/perf_tool.h"
#include <string.h>
#include <sys/utsname.h>
#include <sstream>
#include <base/memory/scoped_ptr.h>
#include <base/strings/string_util.h>
#include <gtest/gtest.h>
#include "debugd/src/random_selector.h"
namespace debugd {
namespace {
// Mock version of Random selector that just stores the odds file path, without
// reading from it. This allows us to test the file path strings without needing
// them to exist.
class MockRandomSelector : public RandomSelector {
public:
// Override the SetOddsFromFile() function to simply store the filename.
void SetOddsFromFile(const std::string& filename) override {
filename_ = filename;
}
const std::string& filename() const {
return filename_;
}
private:
std::string filename_;
};
// Construct mock /proc/cpuinfo contents.
CPUInfoParser MakeMockCPUInfo(const char* model_name, int intel_model) {
const bool is_intel = intel_model != 0;
std::stringstream contents;
if (is_intel) {
contents
<< "processor\t: 0\n"
<< "vendor_id\t: GenuineIntel\n"
<< "cpu family\t: 6\n"
<< "model\t\t: " << intel_model << "\n"
<< "model name\t: " << model_name << "\n"
<< "\n";
} else {
contents
<< "processor\t: 0\n"
<< "vendor_id\t: OtherVendor\n"
<< "model name\t: " << model_name << "\n"
<< "\n";
}
return CPUInfoParser(CPUInfoParser::SET_CONTENTS, contents.str());
}
PerfTool::UnameFunc MakeMockUnameFunc(const char* arch) {
return [arch](struct utsname* buf) -> int {
strncpy(buf->machine, arch, sizeof(buf->machine));
return 0;
};
}
} // namespace
// Tests the CPU odds file lookup against various CPU architecture and CPU model
// name strings.
TEST(PerfToolTest, TestCPUOddsFileLookup) {
// Use a struct to define the expected outputs for each set of inputs.
const struct {
// Inputs.
const char* arch;
const char* model_name;
uint8_t intel_model;
// Expected output.
const char* filename;
} kOddsFileTestCases[] = {
// 64-bit x86.
{ .arch = "x86_64",
.model_name = "Intel(R) Celeron(R) 2955U @ 1.40GHz",
.intel_model = 0x45, // Haswell
.filename = "/etc/perf_commands/x86_64/Haswell.txt" },
{ .arch = "x86_64",
.model_name = "Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz",
.intel_model = 0x2A, // SandyBridge
.filename = "/etc/perf_commands/x86_64/SandyBridge.txt" },
{ .arch = "x86_64",
.model_name = "Intel(R) Core(TM) i5-3427U CPU @ 1.80GHz",
.intel_model = 0x3A, // IvyBridge
.filename = "/etc/perf_commands/x86_64/IvyBridge.txt" },
{ .arch = "x86_64",
.model_name = "Intel(R) Celeron(R) CPU 867 @ 1.30GHz",
.intel_model = 0x2A, // SandyBridge
.filename = "/etc/perf_commands/x86_64/SandyBridge.txt" },
{ .arch = "x86_64",
.model_name = "Intel(R) Celeron(R) CPU 847 @ 1.10GHz",
.intel_model = 0x2A, // SandyBridge
.filename = "/etc/perf_commands/x86_64/SandyBridge.txt" },
{ .arch = "x86_64",
.model_name = "Intel(R) Celeron(R) CPU N2830 @ 2.13GHz",
.intel_model = 0x37, // Silvermont
.filename = "/etc/perf_commands/x86_64/default.txt" },
// 32-bit x86.
{ .arch = "i686",
.model_name = "Intel(R) Atom(TM) CPU N455 @ 1.66GHz",
.intel_model = 0x1C, // Bonnell
.filename = "/etc/perf_commands/i686/default.txt" },
{ .arch = "i686",
.model_name = "Intel(R) Atom(TM) CPU N570 @ 1.66GHz",
.intel_model = 0x1C, // Bonnell
.filename = "/etc/perf_commands/i686/default.txt" },
{ .arch = "i686",
.model_name = "Intel(R) Pentium(TM) M 1.3 @ 1.3GHz",
.intel_model = 0x0D, // Dothan (probably)
.filename = "/etc/perf_commands/i686/default.txt" },
{ .arch = "i686",
.model_name = "Intel(R) Pentium(TM) M 705 @ 1.5GHz",
.intel_model = 0x09, // Banias
.filename = "/etc/perf_commands/i686/default.txt" },
// ARMv7
{ .arch = "armv7l",
.model_name = "ARMv7 Processor rev 3 (v7l)",
.intel_model = 0,
.filename = "/etc/perf_commands/armv7l/default.txt" },
{ .arch = "armv7l",
.model_name = "ARMv7 Processor rev 4 (v7l)",
.intel_model = 0,
.filename = "/etc/perf_commands/armv7l/default.txt" },
// Misc.
{ .arch = "MIPS",
.model_name = "blah",
.intel_model = 0,
.filename = "/etc/perf_commands/unknown.txt" },
{ .arch = "AVR",
.model_name = "blah",
.intel_model = 0,
.filename = "/etc/perf_commands/unknown.txt" },
{ .arch = "MC68000",
.model_name = "blah",
.intel_model = 0,
.filename = "/etc/perf_commands/unknown.txt" },
};
for (const auto& test_case : kOddsFileTestCases) {
// Instantiate a PerfTool with custom inputs.
// |random_selector| will be deleted by PerfTool's destructor.
MockRandomSelector* random_selector = new MockRandomSelector;
std::unique_ptr<MockRandomSelector> random_selector_ptr(random_selector);
PerfTool perf_tool(
MakeMockCPUInfo(test_case.model_name, test_case.intel_model),
random_selector_ptr.release(),
MakeMockUnameFunc(test_case.arch));
// Check if PerfTool has passed the correct path to our MockRandomSelector.
EXPECT_EQ(test_case.filename, random_selector->filename());
}
}
} // namespace debugd