mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
6899cb9d7e
Summary: Add code on macOS to collect the process's resident set size and virtual size so the memory usage counter shows up. Reviewed By: wez Differential Revision: D18142618 fbshipit-source-id: b42206017ace5309b7bc379f042c1cd6e455f574
172 lines
5.1 KiB
C++
172 lines
5.1 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#include "eden/fs/utils/ProcUtil.h"
|
|
|
|
#include <fstream>
|
|
|
|
#include <eden/fs/utils/PathFuncs.h>
|
|
#include <folly/Portability.h>
|
|
#include <folly/portability/GTest.h>
|
|
|
|
using namespace facebook::eden;
|
|
using namespace facebook::eden::proc_util;
|
|
|
|
TEST(proc_util, trimTest) {
|
|
std::string tst("");
|
|
EXPECT_EQ(proc_util::trim(tst), "");
|
|
|
|
tst = " spaceBefore";
|
|
EXPECT_EQ(proc_util::trim(tst), "spaceBefore");
|
|
|
|
tst = "spaceAfter ";
|
|
EXPECT_EQ(proc_util::trim(tst), "spaceAfter");
|
|
|
|
tst = " spaceBeforeAfter ";
|
|
EXPECT_EQ(proc_util::trim(tst), "spaceBeforeAfter");
|
|
|
|
tst = " space between ";
|
|
EXPECT_EQ(proc_util::trim(tst), "space between");
|
|
|
|
tst = "noSpaces";
|
|
EXPECT_EQ(proc_util::trim(tst), "noSpaces");
|
|
|
|
tst = " \t\n\v\f\r";
|
|
EXPECT_EQ(proc_util::trim(tst), "");
|
|
|
|
tst = " \t\n\v\f\rtheGoods \t\n\v\f\r";
|
|
EXPECT_EQ(proc_util::trim(tst), "theGoods");
|
|
|
|
tst = "start \t\n\v\f\rend";
|
|
EXPECT_EQ(proc_util::trim(tst), "start \t\n\v\f\rend");
|
|
}
|
|
|
|
TEST(proc_util, splitTest) {
|
|
std::string line;
|
|
|
|
line = "key : value";
|
|
auto kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "key");
|
|
EXPECT_EQ(kvPair.second, "value");
|
|
|
|
line = " key : value ";
|
|
kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "key");
|
|
EXPECT_EQ(kvPair.second, "value");
|
|
|
|
line = "extra:colon:";
|
|
kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "");
|
|
EXPECT_EQ(kvPair.second, "");
|
|
|
|
line = "noColonHere";
|
|
kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "");
|
|
EXPECT_EQ(kvPair.second, "");
|
|
|
|
line = ":value";
|
|
kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "");
|
|
EXPECT_EQ(kvPair.second, "value");
|
|
|
|
line = ":";
|
|
kvPair = proc_util::getKeyValuePair(line, ":");
|
|
EXPECT_EQ(kvPair.first, "");
|
|
EXPECT_EQ(kvPair.second, "");
|
|
}
|
|
|
|
static AbsolutePath dataPath(PathComponentPiece name) {
|
|
auto thisFile = realpath(__FILE__);
|
|
return thisFile.dirname() + "test-data"_relpath + name;
|
|
}
|
|
|
|
TEST(proc_util, readMemoryStats) {
|
|
auto stats = readMemoryStats();
|
|
if (!stats) {
|
|
EXPECT_FALSE(folly::kIsLinux);
|
|
return;
|
|
}
|
|
|
|
EXPECT_GT(stats->vsize, 0);
|
|
EXPECT_GT(stats->resident, 0);
|
|
if (folly::kIsLinux) {
|
|
EXPECT_GT(*stats->shared, 0);
|
|
EXPECT_GT(*stats->text, 0);
|
|
EXPECT_GT(*stats->data, 0);
|
|
}
|
|
EXPECT_GE(stats->vsize, stats->resident);
|
|
if (folly::kIsLinux) {
|
|
EXPECT_GE(stats->vsize, stats->text);
|
|
EXPECT_GE(stats->vsize, stats->data);
|
|
}
|
|
}
|
|
|
|
TEST(proc_util, parseMemoryStats) {
|
|
size_t pageSize = 4096;
|
|
auto stats = parseStatmFile("26995 164 145 11 0 80 0\n", pageSize);
|
|
ASSERT_TRUE(stats.has_value());
|
|
EXPECT_EQ(pageSize * 26995, stats->vsize);
|
|
EXPECT_EQ(pageSize * 164, stats->resident);
|
|
EXPECT_EQ(pageSize * 145, stats->shared);
|
|
EXPECT_EQ(pageSize * 11, stats->text);
|
|
EXPECT_EQ(pageSize * 80, stats->data);
|
|
|
|
stats = parseStatmFile("6418297 547249 17716 22695 0 1657632 0\n", pageSize);
|
|
EXPECT_EQ(pageSize * 6418297, stats->vsize);
|
|
EXPECT_EQ(pageSize * 547249, stats->resident);
|
|
EXPECT_EQ(pageSize * 17716, stats->shared);
|
|
EXPECT_EQ(pageSize * 22695, stats->text);
|
|
EXPECT_EQ(pageSize * 1657632, stats->data);
|
|
}
|
|
|
|
TEST(proc_util, procStatusSomeInvalidInput) {
|
|
EXPECT_FALSE(parseStatmFile("26995 164 145 11 0\n", 4096));
|
|
EXPECT_FALSE(parseStatmFile("abc 547249 17716 22695 0 1657632 0\n", 4096));
|
|
EXPECT_FALSE(
|
|
parseStatmFile("6418297 547249 foobar 22695 0 1657632 0\n", 4096));
|
|
EXPECT_FALSE(parseStatmFile("6418297 547249 17716", 4096));
|
|
EXPECT_FALSE(
|
|
parseStatmFile("6418297 -547249 17716 22695 0 1657632 0\n", 4096));
|
|
EXPECT_FALSE(parseStatmFile("6418297 0x14 17716 22695 0 1657632 0\n", 4096));
|
|
|
|
EXPECT_TRUE(parseStatmFile("6418297 547249 17716 22695 0 1657632 0\n", 4096));
|
|
}
|
|
|
|
TEST(proc_util, readMemoryStatsNoThrow) {
|
|
auto stats = readStatmFile("/DOES_NOT_EXIST");
|
|
EXPECT_FALSE(stats.has_value());
|
|
}
|
|
|
|
TEST(proc_util, procSmapsPrivateBytes) {
|
|
auto procPath = dataPath("ProcSmapsSimple.txt"_pc);
|
|
std::ifstream input(procPath.c_str());
|
|
auto smapsListOfMaps = proc_util::parseProcSmaps(input);
|
|
auto privateBytes = proc_util::calculatePrivateBytes(smapsListOfMaps).value();
|
|
EXPECT_EQ(privateBytes, 20 * 1024);
|
|
}
|
|
|
|
TEST(proc_util, procSmapsSomeInvalidInput) {
|
|
auto procPath = dataPath("ProcSmapsError.txt"_pc);
|
|
auto smapsListOfMaps = proc_util::loadProcSmaps(procPath.c_str());
|
|
auto privateBytes = proc_util::calculatePrivateBytes(smapsListOfMaps).value();
|
|
EXPECT_EQ(privateBytes, 4096);
|
|
}
|
|
|
|
TEST(proc_util, procSmapsUnknownFormat) {
|
|
auto procPath = dataPath("ProcSmapsUnknownFormat.txt"_pc);
|
|
auto smapsListOfMaps = proc_util::loadProcSmaps(procPath.c_str());
|
|
auto privateBytes = proc_util::calculatePrivateBytes(smapsListOfMaps);
|
|
EXPECT_EQ(privateBytes, std::nullopt);
|
|
}
|
|
|
|
TEST(proc_util, noProcSmapsNoThrow) {
|
|
std::string procPath("/DOES_NOT_EXIST");
|
|
auto smapsListOfMaps = proc_util::loadProcSmaps(procPath);
|
|
auto privateBytes = proc_util::calculatePrivateBytes(smapsListOfMaps).value();
|
|
EXPECT_EQ(privateBytes, 0);
|
|
}
|