Repository: mesos Updated Branches: refs/heads/master a4b39beec -> 777a0c533
Relax perf version check for Arch Linux. Review: https://reviews.apache.org/r/56611/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/777a0c53 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/777a0c53 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/777a0c53 Branch: refs/heads/master Commit: 777a0c533b06a0f147df1ce192f8369ae583faf3 Parents: a4b39be Author: James Peach <[email protected]> Authored: Mon Feb 27 21:52:08 2017 -0800 Committer: Neil Conway <[email protected]> Committed: Tue Feb 28 11:27:24 2017 -0800 ---------------------------------------------------------------------- src/linux/perf.cpp | 36 ++++++++++++++++++----------- src/linux/perf.hpp | 4 ++++ src/tests/containerizer/perf_tests.cpp | 36 ++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/777a0c53/src/linux/perf.cpp ---------------------------------------------------------------------- diff --git a/src/linux/perf.cpp b/src/linux/perf.cpp index 3141e5e..2271564 100644 --- a/src/linux/perf.cpp +++ b/src/linux/perf.cpp @@ -200,24 +200,32 @@ Future<Version> version() return output .then([](const string& output) -> Future<Version> { - string trimmed = strings::remove( - strings::trim(output), "perf version ", strings::PREFIX); - - // `perf` may have a version like "4.8.16.300.fc25.x86_64.ge69a". - // We really only care about the first 3 components, which show - // the software release of the perf package. - vector<string> components = strings::split(trimmed, "."); - if (components.size() > 3) { - components.resize(3); - trimmed = strings::join(".", components); - } - - // Trim off the leading 'perf version ' text to convert. - return Version::parse(trimmed); + return parseVersion(output); }); }; +// Since there is a lot of variety in perf(1) version strings +// across distributions, we parse just the first 2 version +// components, which is enough of a version number to implement +// perf::supported(). +Try<Version> parseVersion(const string& output) +{ + // Trim off the leading 'perf version ' text to convert. + string trimmed = strings::remove( + strings::trim(output), "perf version ", strings::PREFIX); + + vector<string> components = strings::split(trimmed, "."); + + // perf(1) always has a version with least 2 components. + if (components.size() > 2) { + components.resize(2); + } + + return Version::parse(strings::join(".", components)); +} + + bool supported(const Version& version) { // Require perf version >= 2.6.39 to support cgroups and formatting. http://git-wip-us.apache.org/repos/asf/mesos/blob/777a0c53/src/linux/perf.hpp ---------------------------------------------------------------------- diff --git a/src/linux/perf.hpp b/src/linux/perf.hpp index 9c4330b..20ebcf1 100644 --- a/src/linux/perf.hpp +++ b/src/linux/perf.hpp @@ -56,6 +56,10 @@ bool supported(); process::Future<Version> version(); +// Parse a perf(1) version string. Exposed for testing. +Try<Version> parseVersion(const std::string& output); + + // Note: The parse function is exposed to allow testing of the // multiple supported perf stat output formats. Try<hashmap<std::string, mesos::PerfStatistics>> parse( http://git-wip-us.apache.org/repos/asf/mesos/blob/777a0c53/src/tests/containerizer/perf_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/perf_tests.cpp b/src/tests/containerizer/perf_tests.cpp index d536ecc..e2d7860 100644 --- a/src/tests/containerizer/perf_tests.cpp +++ b/src/tests/containerizer/perf_tests.cpp @@ -27,6 +27,10 @@ #include <stout/os.hpp> #include <stout/stringify.hpp> +#include <stout/os/shell.hpp> + +#include "common/status_utils.hpp" + #include "linux/perf.hpp" using std::set; @@ -128,11 +132,37 @@ TEST_F(PerfTest, Parse) // the version check performed in the test filter fails. TEST_F(PerfTest, Version) { - Option<string> perf = os::which("perf"); - - if (perf.isSome()) { + // If there is a "perf" command that can successfully emit its + // version, make sure we can parse it using the perf library. + // Note that on some systems, perf is a stub that asks you to + // install the right packages. + if (WSUCCEEDED(os::spawn("perf", {"perf", "--version"}))) { AWAIT_READY(perf::version()); } + + EXPECT_SOME_EQ(Version(1, 0, 0), perf::parseVersion("1")); + EXPECT_SOME_EQ(Version(1, 2, 0), perf::parseVersion("1.2")); + EXPECT_SOME_EQ(Version(1, 2, 0), perf::parseVersion("1.2.3")); + EXPECT_SOME_EQ(Version(0, 0, 0), perf::parseVersion("0.0.0")); + + // Fedora 25. + EXPECT_SOME_EQ( + Version(4, 8, 0), + perf::parseVersion("4.8.16.300.fc25.x86_64.ge69a")); + + // Arch Linux. + EXPECT_SOME_EQ( + Version(4, 9, 0), + perf::parseVersion("4.9.g69973b")); + + // CentOS 6.8. + EXPECT_SOME_EQ( + Version(2, 6, 0), + perf::parseVersion("2.6.32-642.13.1.el6.x86_64.debug")); + + EXPECT_ERROR(perf::parseVersion("")); + EXPECT_ERROR(perf::parseVersion("foo")); + EXPECT_ERROR(perf::parseVersion("1.foo")); } } // namespace tests {
