diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index d65b78571..2307fc6ec 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2140,6 +2140,7 @@ cc_binary( "//test/util:test_main", "//test/util:test_util", "//test/util:thread_util", + "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/strings", ], ) @@ -4143,6 +4144,7 @@ cc_binary( linkstatic = 1, deps = [ "//test/util:fs_util", + "@com_google_absl//absl/algorithm:container", gtest, "//test/util:posix_error", "//test/util:proc_util", diff --git a/test/syscalls/linux/rlimits.cc b/test/syscalls/linux/rlimits.cc index a8dec2190..fb2f39b6c 100644 --- a/test/syscalls/linux/rlimits.cc +++ b/test/syscalls/linux/rlimits.cc @@ -25,6 +25,7 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/strings/numbers.h" #include "absl/strings/str_split.h" #include "test/util/capability_util.h" @@ -41,12 +42,12 @@ PosixErrorOr GetProcLimitEntryByType(LimitType limit_type) { ASSIGN_OR_RETURN_ERRNO(std::string proc_self_limits, GetContents("/proc/self/limits")); ASSIGN_OR_RETURN_ERRNO(auto entries, ParseProcLimits(proc_self_limits)); - auto it = std::find_if(entries.begin(), entries.end(), - [limit_type](const ProcLimitsEntry& v) { - return v.limit_type == limit_type; - }); + auto it = absl::c_find_if(entries, [limit_type](const ProcLimitsEntry& v) { + return v.limit_type == limit_type; + }); if (it == entries.end()) { - return PosixError(ENOENT, "limit type not found"); + return PosixError(ENOENT, absl::StrFormat("limit type \"%s\" not found", + LimitTypeToString(limit_type))); } return *it; } @@ -65,7 +66,7 @@ TEST(RlimitTest, SetRlimitHigher) { // Now verify we can read the changed values via /proc/self/limits const ProcLimitsEntry limit_entry = ASSERT_NO_ERRNO_AND_VALUE( - GetProcLimitEntryByType(LimitType::NumberOfFiles)); + GetProcLimitEntryByType(LimitType::kNumberOfFiles)); EXPECT_EQ(rl.rlim_cur, limit_entry.cur_limit); EXPECT_EQ(rl.rlim_max, limit_entry.max_limit); @@ -154,6 +155,13 @@ TEST(RlimitTest, RlimitNProc) { }).Join(); } +TEST(RlimitTest, ParseProcPidLimits) { + auto proc_self_limits = + ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/self/limits")); + auto entries = ASSERT_NO_ERRNO_AND_VALUE(ParseProcLimits(proc_self_limits)); + EXPECT_EQ(entries.size(), LimitTypes.size()); +} + } // namespace } // namespace testing diff --git a/test/syscalls/linux/vdso.cc b/test/syscalls/linux/vdso.cc index 19c80add8..0551ab67a 100644 --- a/test/syscalls/linux/vdso.cc +++ b/test/syscalls/linux/vdso.cc @@ -18,6 +18,7 @@ #include #include "gtest/gtest.h" +#include "absl/algorithm/container.h" #include "test/util/fs_util.h" #include "test/util/posix_error.h" #include "test/util/proc_util.h" @@ -32,9 +33,8 @@ namespace { TEST(VvarTest, WriteVvar) { auto contents = ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/self/maps")); auto maps = ASSERT_NO_ERRNO_AND_VALUE(ParseProcMaps(contents)); - auto it = std::find_if(maps.begin(), maps.end(), [](const ProcMapsEntry& e) { - return e.filename == "[vvar]"; - }); + auto it = absl::c_find_if( + maps, [](const ProcMapsEntry& e) { return e.filename == "[vvar]"; }); SKIP_IF(it == maps.end()); EXPECT_THAT(mprotect(reinterpret_cast(it->start), kPageSize, diff --git a/test/util/BUILD b/test/util/BUILD index e329d6bba..73ff61f81 100644 --- a/test/util/BUILD +++ b/test/util/BUILD @@ -82,6 +82,7 @@ cc_library( ":fs_util", ":posix_error", ":test_util", + "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:optional", diff --git a/test/util/proc_util.cc b/test/util/proc_util.cc index fa280feca..cda299542 100644 --- a/test/util/proc_util.cc +++ b/test/util/proc_util.cc @@ -20,6 +20,7 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/container/flat_hash_set.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" @@ -284,7 +285,7 @@ PosixErrorOr FindUniqueSmapsEntry( auto const pred = [&](ProcSmapsEntry const& entry) { return entry.maps_entry.start <= addr && addr < entry.maps_entry.end; }; - auto const it = std::find_if(entries.begin(), entries.end(), pred); + auto const it = absl::c_find_if(entries, pred); if (it == entries.end()) { return PosixError(EINVAL, absl::StrFormat("no entry contains address %#x", addr)); @@ -331,6 +332,45 @@ bool IsTHPDisabled() { return StackTHPDisabled(maps.ValueOrDie()); } +std::string LimitTypeToString(LimitType type) { + switch (type) { + case LimitType::kCPU: + return "cpu time"; + case LimitType::kFileSize: + return "file size"; + case LimitType::kData: + return "data size"; + case LimitType::kStack: + return "stack size"; + case LimitType::kCore: + return "core file size"; + case LimitType::kRSS: + return "resident set"; + case LimitType::kProcessCount: + return "processes"; + case LimitType::kNumberOfFiles: + return "open files"; + case LimitType::kMemoryLocked: + return "locked memory"; + case LimitType::kAS: + return "address space"; + case LimitType::kLocks: + return "file locks"; + case LimitType::kSignalsPending: + return "pending signals"; + case LimitType::kMessageQueueBytes: + return "msgqueue size"; + case LimitType::kNice: + return "nice priority"; + case LimitType::kRealTimePriority: + return "realtime priority"; + case LimitType::kRttime: + return "realtime timeout"; + default: + return "unknown"; + } +} + PosixErrorOr ParseProcLimitsLine(absl::string_view line) { ProcLimitsEntry limits_entry = {}; @@ -348,41 +388,13 @@ PosixErrorOr ParseProcLimitsLine(absl::string_view line) { // parse the limit type auto limitType = line.substr(0, 25); - if (absl::StrContains(limitType, "cpu time")) { - limits_entry.limit_type = LimitType::CPU; - } else if (absl::StrContains(limitType, "file size")) { - limits_entry.limit_type = LimitType::FileSize; - } else if (absl::StrContains(limitType, "data size")) { - limits_entry.limit_type = LimitType::Data; - } else if (absl::StrContains(limitType, "stack size")) { - limits_entry.limit_type = LimitType::Stack; - } else if (absl::StrContains(limitType, "core file size")) { - limits_entry.limit_type = LimitType::Core; - } else if (absl::StrContains(limitType, "resident set")) { - limits_entry.limit_type = LimitType::RSS; - } else if (absl::StrContains(limitType, "processes")) { - limits_entry.limit_type = LimitType::ProcessCount; - } else if (absl::StrContains(limitType, "open files")) { - limits_entry.limit_type = LimitType::NumberOfFiles; - } else if (absl::StrContains(limitType, "locked memory")) { - limits_entry.limit_type = LimitType::MemoryLocked; - } else if (absl::StrContains(limitType, "address space")) { - limits_entry.limit_type = LimitType::AS; - } else if (absl::StrContains(limitType, "file locks")) { - limits_entry.limit_type = LimitType::Locks; - } else if (absl::StrContains(limitType, "pending signals")) { - limits_entry.limit_type = LimitType::SignalsPending; - } else if (absl::StrContains(limitType, "msgqueue size")) { - limits_entry.limit_type = LimitType::MessageQueueBytes; - } else if (absl::StrContains(limitType, "nice priority")) { - limits_entry.limit_type = LimitType::Nice; - } else if (absl::StrContains(limitType, "realtime priority")) { - limits_entry.limit_type = LimitType::RealTimePriority; - } else if (absl::StrContains(limitType, "realtime timeout")) { - limits_entry.limit_type = LimitType::Rttime; - } else { + auto it = absl::c_find_if(LimitTypes, [&limitType](LimitType t) { + return absl::StrContains(limitType, LimitTypeToString(t)); + }); + if (it == LimitTypes.end()) { return PosixError(EINVAL, absl::StrCat("Invalid limit type: ", limitType)); } + limits_entry.limit_type = *it; // parse soft limit if (parts[0] == "unlimited") { @@ -418,119 +430,55 @@ PosixErrorOr> ParseProcLimits( } std::ostream& operator<<(std::ostream& os, const ProcLimitsEntry& entry) { - std::string str = "Max "; - - switch (entry.limit_type) { - case LimitType::CPU: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "cpu time")); - break; - case LimitType::FileSize: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "file size")); - break; - case LimitType::Data: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "data size")); - break; - case LimitType::Stack: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "stack size")); - break; - case LimitType::Core: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "core file size")); - break; - case LimitType::RSS: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "resident set")); - break; - case LimitType::ProcessCount: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "processes")); - break; - case LimitType::NumberOfFiles: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "open files")); - break; - case LimitType::MemoryLocked: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "locked memory")); - break; - case LimitType::AS: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "address space")); - break; - case LimitType::Locks: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "file locks")); - break; - case LimitType::SignalsPending: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "pending signals")); - break; - case LimitType::MessageQueueBytes: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "msgqueue size")); - break; - case LimitType::Nice: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "nice priority")); - break; - case LimitType::RealTimePriority: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "realtime priority")); - break; - case LimitType::Rttime: - absl::StrAppend(&str, absl::StrFormat("%-25s ", "realtime timeout")); - break; - } + std::string str = + absl::StrFormat("Max %-25s ", LimitTypeToString(entry.limit_type)); if (entry.cur_limit == ~0ULL) { - absl::StrAppend(&str, absl::StrFormat("%-20s ", "unlimited")); + absl::StrAppendFormat(&str, "%-20s ", "unlimited"); } else { - absl::StrAppend(&str, absl::StrFormat("%-20d ", entry.cur_limit)); + absl::StrAppendFormat(&str, "%-20d ", entry.cur_limit); } if (entry.max_limit == ~0ULL) { - absl::StrAppend(&str, absl::StrFormat("%-20s ", "unlimited")); + absl::StrAppendFormat(&str, "%-20s ", "unlimited"); } else { - absl::StrAppend(&str, absl::StrFormat("%-20d ", entry.max_limit)); + absl::StrAppendFormat(&str, "%-20d ", entry.max_limit); } switch (entry.limit_type) { - case LimitType::CPU: - absl::StrAppend(&str, absl::StrFormat("%-10s", "seconds")); + case LimitType::kFileSize: + case LimitType::kData: + case LimitType::kStack: + case LimitType::kCore: + case LimitType::kRSS: + case LimitType::kMemoryLocked: + case LimitType::kAS: + case LimitType::kMessageQueueBytes: + absl::StrAppendFormat(&str, "%-10s ", "bytes"); break; - case LimitType::FileSize: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); + case LimitType::kCPU: + absl::StrAppendFormat(&str, "%-10s", "seconds"); break; - case LimitType::Data: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); + case LimitType::kNumberOfFiles: + absl::StrAppendFormat(&str, "%-10s ", "files"); break; - case LimitType::Stack: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); + case LimitType::kLocks: + absl::StrAppendFormat(&str, "%-10s ", "locks"); break; - case LimitType::Core: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); + case LimitType::kSignalsPending: + absl::StrAppendFormat(&str, "%-10s ", "signals"); break; - case LimitType::RSS: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); + case LimitType::kProcessCount: + absl::StrAppendFormat(&str, "%-10s ", "processes"); break; - case LimitType::ProcessCount: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "processes")); + case LimitType::kNice: + absl::StrAppendFormat(&str, "%-10s ", ""); break; - case LimitType::NumberOfFiles: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "files")); + case LimitType::kRealTimePriority: + absl::StrAppendFormat(&str, "%-10s ", ""); break; - case LimitType::MemoryLocked: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); - break; - case LimitType::AS: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); - break; - case LimitType::Locks: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "locks")); - break; - case LimitType::SignalsPending: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "signals")); - break; - case LimitType::MessageQueueBytes: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "bytes")); - break; - case LimitType::Nice: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "")); - break; - case LimitType::RealTimePriority: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "")); - break; - case LimitType::Rttime: - absl::StrAppend(&str, absl::StrFormat("%-10s ", "us")); + case LimitType::kRttime: + absl::StrAppendFormat(&str, "%-10s ", "us"); break; } diff --git a/test/util/proc_util.h b/test/util/proc_util.h index 8dd4c57db..14b2cc6ca 100644 --- a/test/util/proc_util.h +++ b/test/util/proc_util.h @@ -21,6 +21,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/algorithm/container.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -142,7 +143,7 @@ inline std::ostream& operator<<(std::ostream& os, return os; } -// GMock printer for std::vector. +// GoogleTest printer for std::vector. inline void PrintTo(const std::vector& vec, std::ostream* os) { *os << vec; } @@ -173,7 +174,7 @@ MATCHER_P(ContainsMappings, mappings, bool all_present = true; std::for_each(mappings.begin(), mappings.end(), [&](const ProcMapsEntry& e1) { auto it = - std::find_if(maps.begin(), maps.end(), [&e1](const ProcMapsEntry& e2) { + absl::c_find_if(maps, [&e1](const ProcMapsEntry& e2) { return e1.start == e2.start && e1.end == e2.end && e1.readable == e2.readable && e1.writable == e2.writable && e1.executable == e2.executable && e1.priv == e2.priv && @@ -197,24 +198,45 @@ MATCHER_P(ContainsMappings, mappings, // LimitType is an rlimit type enum class LimitType { - CPU, - FileSize, - Data, - Stack, - Core, - RSS, - ProcessCount, - NumberOfFiles, - MemoryLocked, - AS, - Locks, - SignalsPending, - MessageQueueBytes, - Nice, - RealTimePriority, - Rttime, + kCPU, + kFileSize, + kData, + kStack, + kCore, + kRSS, + kProcessCount, + kNumberOfFiles, + kMemoryLocked, + kAS, + kLocks, + kSignalsPending, + kMessageQueueBytes, + kNice, + kRealTimePriority, + kRttime, }; +const std::vector LimitTypes{ + LimitType::kCPU, + LimitType::kFileSize, + LimitType::kData, + LimitType::kStack, + LimitType::kCore, + LimitType::kRSS, + LimitType::kProcessCount, + LimitType::kNumberOfFiles, + LimitType::kMemoryLocked, + LimitType::kAS, + LimitType::kLocks, + LimitType::kSignalsPending, + LimitType::kMessageQueueBytes, + LimitType::kNice, + LimitType::kRealTimePriority, + LimitType::kRttime, +}; + +std::string LimitTypeToString(LimitType type); + // ProcLimitsEntry contains the data from a single line in /proc/xxx/limits. struct ProcLimitsEntry { LimitType limit_type; @@ -222,10 +244,10 @@ struct ProcLimitsEntry { uint64_t max_limit; }; -// Parses a single line from /proc/xxx/limits +// Parses a single line from /proc/xxx/limits. PosixErrorOr ParseProcLimitsLine(absl::string_view line); -// Parses an entire /proc/xxx/limits file into lines +// Parses an entire /proc/xxx/limits file into lines. PosixErrorOr> ParseProcLimits( absl::string_view contents); @@ -236,7 +258,7 @@ std::ostream& operator<<(std::ostream& os, const ProcLimitsEntry& entry); std::ostream& operator<<(std::ostream& os, const std::vector& vec); -// GMock printer for std::vector. +// GoogleTest printer for std::vector. inline void PrintTo(const std::vector& vec, std::ostream* os) { *os << vec; }