diff --git a/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.cpp b/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.cpp index cff669ed..a33f5a7a 100644 --- a/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.cpp +++ b/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.cpp @@ -20,6 +20,7 @@ #include "../../src/system_metrics_collector/linux_cpu_measurement_node.hpp" #include "../../src/system_metrics_collector/periodic_measurement_node.hpp" +#include "../../src/system_metrics_collector/utilities.hpp" #include "rclcpp/rclcpp.hpp" #include "rcutils/logging_macros.h" @@ -30,55 +31,11 @@ namespace { constexpr const char MEASUREMENT_TYPE[] = "system_cpu_percent_used"; constexpr const char PROC_STAT_FILE[] = "/proc/stat"; -constexpr const char CPU_LABEL[] = "cpu"; } // namespace namespace system_metrics_collector { -system_metrics_collector::ProcCpuData processStatCpuLine(const std::string & stat_cpu_line) -{ - system_metrics_collector::ProcCpuData parsed_data; - - if (!stat_cpu_line.empty()) { - if (!stat_cpu_line.compare(0, strlen(CPU_LABEL), CPU_LABEL)) { - std::istringstream ss(stat_cpu_line); - - if (!ss.good()) { - return system_metrics_collector::ProcCpuData(); - } - ss >> parsed_data.cpu_label; - - for (int i = 0; - i < static_cast(system_metrics_collector::ProcCpuStates::kNumProcCpuStates); ++i) - { - if (!ss.good()) { - return system_metrics_collector::ProcCpuData(); - } - ss >> parsed_data.times[i]; - } - return parsed_data; - } - } - return parsed_data; -} - -double computeCpuActivePercentage( - const system_metrics_collector::ProcCpuData & measurement1, - const system_metrics_collector::ProcCpuData & measurement2) -{ - if (measurement1.isMeasurementEmpty() || measurement2.isMeasurementEmpty()) { - RCUTILS_LOG_ERROR_NAMED("computeCpuActivePercentage", - "a measurement was empty, unable to compute cpu percentage"); - return std::nan(""); - } - const double active_time = measurement2.getActiveTime() - measurement1.getActiveTime(); - const double total_time = (measurement2.getIdleTime() + measurement2.getActiveTime()) - - (measurement1.getIdleTime() + measurement1.getActiveTime()); - - return 100.0 * active_time / total_time; -} - LinuxCpuMeasurementNode::LinuxCpuMeasurementNode( const std::string & name, const std::chrono::milliseconds measurement_period, diff --git a/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.hpp b/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.hpp index f9b4b0ec..5f15ab47 100644 --- a/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.hpp +++ b/system_metrics_collector/src/system_metrics_collector/linux_cpu_measurement_node.hpp @@ -26,25 +26,6 @@ namespace system_metrics_collector { -/** - * Parse a line read from /proc/stat - * - * @param stat_cpu_line a line from /proc/stat - * @return ProcCpuData struct populated if parsed, otherwise empty - */ -system_metrics_collector::ProcCpuData processStatCpuLine(const std::string & stat_cpu_line); - -/** - * Compute the percentage of CPU active. - * - * @param measurement1 the first measurement - * @param measurement2 the second measurement (made after the first) - * @return percentage of CPU active - */ -double computeCpuActivePercentage( - const system_metrics_collector::ProcCpuData & measurement1, - const system_metrics_collector::ProcCpuData & measurement2); - /** * Node that periodically calculates the % of active CPU by * reading /proc/stat. diff --git a/system_metrics_collector/src/system_metrics_collector/utilities.cpp b/system_metrics_collector/src/system_metrics_collector/utilities.cpp index c43ae3bc..b216d9b4 100644 --- a/system_metrics_collector/src/system_metrics_collector/utilities.cpp +++ b/system_metrics_collector/src/system_metrics_collector/utilities.cpp @@ -28,10 +28,20 @@ namespace system_metrics_collector namespace { + +constexpr const char CPU_LABEL[] = "cpu"; constexpr const char MEM_TOTAL[] = "MemTotal:"; constexpr const char MEM_AVAILABLE[] = "MemAvailable:"; constexpr const char EMPTY_FILE[] = ""; constexpr const int INVALID_MEMORY_SAMPLE = -1; + +double computeCpuTotalTime(const ProcCpuData measurement1, const ProcCpuData measurement2) +{ + const double total_time = (measurement2.getIdleTime() + measurement2.getActiveTime()) - + (measurement1.getIdleTime() + measurement1.getActiveTime()); + return total_time; +} + } // namespace std::string readFileToString(const std::string & file_name) @@ -48,6 +58,49 @@ std::string readFileToString(const std::string & file_name) return to_return; } +ProcCpuData processStatCpuLine(const std::string & stat_cpu_line) +{ + ProcCpuData parsed_data; + + if (!stat_cpu_line.empty()) { + if (!stat_cpu_line.compare(0, strlen(CPU_LABEL), CPU_LABEL)) { + std::istringstream ss(stat_cpu_line); + + if (!ss.good()) { + return ProcCpuData(); + } + ss >> parsed_data.cpu_label; + + for (int i = 0; + i < static_cast(ProcCpuStates::kNumProcCpuStates); ++i) + { + if (!ss.good()) { + return ProcCpuData(); + } + ss >> parsed_data.times[i]; + } + return parsed_data; + } + } + return parsed_data; +} + +double computeCpuActivePercentage( + const ProcCpuData & measurement1, + const ProcCpuData & measurement2) +{ + if (measurement1.isMeasurementEmpty() || measurement2.isMeasurementEmpty()) { + RCUTILS_LOG_ERROR_NAMED("computeCpuActivePercentage", + "a measurement was empty, unable to compute cpu percentage"); + return std::nan(""); + } + + const double active_time = measurement2.getActiveTime() - measurement1.getActiveTime(); + const double total_time = computeCpuTotalTime(measurement1, measurement2); + + return 100.0 * active_time / total_time; +} + double processMemInfoLines(const std::string & lines) { std::istringstream process_lines_stream(lines); diff --git a/system_metrics_collector/src/system_metrics_collector/utilities.hpp b/system_metrics_collector/src/system_metrics_collector/utilities.hpp index 4d54ddf8..bdc21838 100644 --- a/system_metrics_collector/src/system_metrics_collector/utilities.hpp +++ b/system_metrics_collector/src/system_metrics_collector/utilities.hpp @@ -17,6 +17,8 @@ #include +#include "../../src/system_metrics_collector/proc_cpu_data.hpp" + namespace system_metrics_collector { /** @@ -28,6 +30,25 @@ namespace system_metrics_collector */ std::string readFileToString(const std::string & file_name); +/** + * Parse a line read from /proc/stat + * + * @param stat_cpu_line a line from /proc/stat + * @return ProcCpuData struct populated if parsed, otherwise empty + */ +ProcCpuData processStatCpuLine(const std::string & stat_cpu_line); + +/** + * Compute the percentage of CPU active. + * + * @param measurement1 the first measurement + * @param measurement2 the second measurement (made after the first) + * @return percentage of CPU active + */ +double computeCpuActivePercentage( + const ProcCpuData & measurement1, + const ProcCpuData & measurement2); + /** * Process input lines from the /proc/meminfo file. The expected format to * compute memory used is diff --git a/system_metrics_collector/test/system_metrics_collector/test_constants.hpp b/system_metrics_collector/test/system_metrics_collector/test_constants.hpp index 6d4a4f35..c86884a7 100644 --- a/system_metrics_collector/test/system_metrics_collector/test_constants.hpp +++ b/system_metrics_collector/test/system_metrics_collector/test_constants.hpp @@ -24,6 +24,23 @@ constexpr const std::chrono::milliseconds TEST_DURATION{250}; constexpr const std::chrono::milliseconds MEASURE_PERIOD{50}; constexpr const std::chrono::milliseconds PUBLISH_PERIOD{80}; +constexpr const char PROC_SAMPLE_RESOLUTION_TEST[] = + "cpu 57211920 335926 18096939 2526329830 14818556 0 1072048 0 0 0\n"; +constexpr const std::array PROC_SAMPLES = { + "cpu 22451232 118653 7348045 934943300 5378119 0 419114 0 0 0\n", + "cpu 22451360 118653 7348080 934949227 5378120 0 419117 0 0 0\n", + "cpu 24343452 61856 6484430 10645595 58695 0 683052 0 0 0\n", + "cpu 6051294 43322 1611333 9021635 47400 0 177494 0 0 0\n", + "cpu 6092443 6217 1623536 535731 4143 0 232286 0 0 0\n", + "cpu 6097071 6498 1612044 544445 3484 0 135942 0 0 0\n", + "cpu 6102643 5818 1637516 543782 3666 0 137329 0 0 0\n", + "cpu 24513632 62372 6527524 11205004 62394 0 687176 0 0 0\n", + "cpu 6093617 43419 1621953 9161570 48047 0 178792 0 0 0\n", + "cpu 6134250 6371 1634411 675446 5285 0 233478 0 0 0\n" +}; +constexpr const double CPU_ACTIVE_PROC_SAMPLE_0_1 = 2.7239908106334099; + + constexpr const char EMPTY_SAMPLE[] = ""; constexpr const char GARBAGE_SAMPLE[] = "this is garbage\n"; constexpr const char INCOMPLETE_SAMPLE[] = diff --git a/system_metrics_collector/test/system_metrics_collector/test_linux_cpu_measurement.cpp b/system_metrics_collector/test/system_metrics_collector/test_linux_cpu_measurement.cpp index 6ee702b8..96a749e9 100644 --- a/system_metrics_collector/test/system_metrics_collector/test_linux_cpu_measurement.cpp +++ b/system_metrics_collector/test/system_metrics_collector/test_linux_cpu_measurement.cpp @@ -28,43 +28,24 @@ #include "../../src/system_metrics_collector/linux_cpu_measurement_node.hpp" #include "../../src/system_metrics_collector/proc_cpu_data.hpp" +#include "../../src/system_metrics_collector/utilities.hpp" #include "test_constants.hpp" +#include "test_utilities.hpp" using metrics_statistics_msgs::msg::MetricsMessage; using metrics_statistics_msgs::msg::StatisticDataPoint; using metrics_statistics_msgs::msg::StatisticDataType; using moving_average_statistics::StatisticData; using system_metrics_collector::processStatCpuLine; +using test_constants::PROC_SAMPLES; +using test_utilities::computeCpuActivePercentage; namespace { constexpr const char TEST_NODE_NAME[] = "test_measure_linux_cpu"; constexpr const char TEST_TOPIC[] = "test_cpu_measure_topic"; constexpr const char TEST_METRIC_NAME[] = "system_cpu_percent_used"; - -constexpr const std::array proc_samples = { - "cpu 22451232 118653 7348045 934943300 5378119 0 419114 0 0 0\n", - "cpu 22451360 118653 7348080 934949227 5378120 0 419117 0 0 0\n", - "cpu 24343452 61856 6484430 10645595 58695 0 683052 0 0 0\n", - "cpu 6051294 43322 1611333 9021635 47400 0 177494 0 0 0\n", - "cpu 6092443 6217 1623536 535731 4143 0 232286 0 0 0\n", - "cpu 6097071 6498 1612044 544445 3484 0 135942 0 0 0\n", - "cpu 6102643 5818 1637516 543782 3666 0 137329 0 0 0\n", - "cpu 24513632 62372 6527524 11205004 62394 0 687176 0 0 0\n", - "cpu 6093617 43419 1621953 9161570 48047 0 178792 0 0 0\n", - "cpu 6134250 6371 1634411 675446 5285 0 233478 0 0 0\n" -}; -constexpr const double CPU_ACTIVE_PROC_SAMPLE_0_1 = 2.7239908106334099; -constexpr const char proc_sample_resolution_test[] = - "cpu 57211920 335926 18096939 2526329830 14818556 0 1072048 0 0 0\n"; - -double computeCpuActivePercentage(const std::string & data1, const std::string & data2) -{ - auto parsed_data1 = processStatCpuLine(data1); - auto parsed_data2 = processStatCpuLine(data2); - return computeCpuActivePercentage(parsed_data1, parsed_data2); -} } // namespace @@ -88,8 +69,8 @@ class TestLinuxCpuMeasurementNode : public system_metrics_collector::LinuxCpuMea private: system_metrics_collector::ProcCpuData makeSingleMeasurement() override { - EXPECT_GT(proc_samples.size(), measurement_index); - return processStatCpuLine(proc_samples[measurement_index++]); + EXPECT_GT(PROC_SAMPLES.size(), measurement_index); + return processStatCpuLine(PROC_SAMPLES[measurement_index++]); } int measurement_index{0}; @@ -110,52 +91,52 @@ class TestReceiveCpuMeasurementNode : public rclcpp::Node StatisticData data; // setting expected_stats[0] - // round 1 50 ms: proc_samples[0] is collected - // round 1 80 ms: statistics derived from proc_samples[N/A-0] is published + // round 1 50 ms: PROC_SAMPLES[0] is collected + // round 1 80 ms: statistics derived from PROC_SAMPLES[N/A-0] is published stats_calc.reset(); data = StatisticData(); StatisticDataToExpectedStatistics(data, expected_stats[0]); // setting expected_stats[1] - // round 1 100 ms: proc_samples[1] is collected - // round 1 150 ms: proc_samples[2] is collected - // round 1 160 ms: statistics derived from proc_samples[0-1 & 1-2] is published + // round 1 100 ms: PROC_SAMPLES[1] is collected + // round 1 150 ms: PROC_SAMPLES[2] is collected + // round 1 160 ms: statistics derived from PROC_SAMPLES[0-1 & 1-2] is published stats_calc.reset(); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[0], proc_samples[1])); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[1], proc_samples[2])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[0], PROC_SAMPLES[1])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[1], PROC_SAMPLES[2])); data = stats_calc.getStatistics(); StatisticDataToExpectedStatistics(data, expected_stats[1]); // setting expected_stats[2] - // round 1 200 ms: proc_samples[3] is collected - // round 1 240 ms: statistics derived from proc_samples[2-3] is published + // round 1 200 ms: PROC_SAMPLES[3] is collected + // round 1 240 ms: statistics derived from PROC_SAMPLES[2-3] is published stats_calc.reset(); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[2], proc_samples[3])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[2], PROC_SAMPLES[3])); data = stats_calc.getStatistics(); StatisticDataToExpectedStatistics(data, expected_stats[2]); // setting expected_stats[3] - // round 2 50 ms: proc_samples[5] is collected - // round 2 80 ms: statistics derived from proc_samples[N/A-5] is published + // round 2 50 ms: PROC_SAMPLES[5] is collected + // round 2 80 ms: statistics derived from PROC_SAMPLES[N/A-5] is published stats_calc.reset(); data = StatisticData(); StatisticDataToExpectedStatistics(data, expected_stats[3]); // setting expected_stats[4] - // round 2 100 ms: proc_samples[6] is collected - // round 2 150 ms: proc_samples[7] is collected - // round 2 160 ms: statistics derived from proc_samples[5-6 & 6-7] is published + // round 2 100 ms: PROC_SAMPLES[6] is collected + // round 2 150 ms: PROC_SAMPLES[7] is collected + // round 2 160 ms: statistics derived from PROC_SAMPLES[5-6 & 6-7] is published stats_calc.reset(); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[5], proc_samples[6])); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[6], proc_samples[7])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[5], PROC_SAMPLES[6])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[6], PROC_SAMPLES[7])); data = stats_calc.getStatistics(); StatisticDataToExpectedStatistics(data, expected_stats[4]); // setting expected_stats[5] - // round 2 200 ms: proc_samples[8] is collected - // round 2 240 ms: statistics derived from proc_samples[7-8] is published + // round 2 200 ms: PROC_SAMPLES[8] is collected + // round 2 240 ms: statistics derived from PROC_SAMPLES[7-8] is published stats_calc.reset(); - stats_calc.addMeasurement(computeCpuActivePercentage(proc_samples[7], proc_samples[8])); + stats_calc.addMeasurement(computeCpuActivePercentage(PROC_SAMPLES[7], PROC_SAMPLES[8])); data = stats_calc.getStatistics(); StatisticDataToExpectedStatistics(data, expected_stats[5]); } @@ -245,65 +226,7 @@ TEST_F(LinuxCpuMeasurementTestFixture, testManualMeasurement) ASSERT_TRUE(std::isnan(cpu_active_percentage)); // second measurement compares current and cached cpu_active_percentage = test_measure_linux_cpu->periodicMeasurement(); - ASSERT_DOUBLE_EQ(CPU_ACTIVE_PROC_SAMPLE_0_1, cpu_active_percentage); -} - -TEST(LinuxCpuMeasurementTest, testParseProcLine) -{ - auto parsed_data = processStatCpuLine(proc_samples[0]); - - ASSERT_EQ("cpu", parsed_data.cpu_label); - ASSERT_EQ(22451232, parsed_data.times[0]); - ASSERT_EQ(118653, parsed_data.times[1]); - ASSERT_EQ(7348045, parsed_data.times[2]); - ASSERT_EQ(934943300, parsed_data.times[3]); - ASSERT_EQ(5378119, parsed_data.times[4]); - ASSERT_EQ(0, parsed_data.times[5]); - ASSERT_EQ(419114, parsed_data.times[6]); - ASSERT_EQ(0, parsed_data.times[7]); - - ASSERT_EQ( - "cpu_label=cpu, user=22451232, nice=118653, system=7348045, idle=934943300," - " iOWait=5378119, irq=0, softIrq=419114, steal=0", - parsed_data.toString()); -} - -TEST(LinuxCpuMeasurementTest, testParseProcLine2) -{ - auto parsed_data = system_metrics_collector::processStatCpuLine(proc_sample_resolution_test); - - ASSERT_EQ("cpu", parsed_data.cpu_label); - ASSERT_EQ(57211920, parsed_data.times[0]); - ASSERT_EQ(335926, parsed_data.times[1]); - ASSERT_EQ(18096939, parsed_data.times[2]); - ASSERT_EQ(2526329830, parsed_data.times[3]); - ASSERT_EQ(14818556, parsed_data.times[4]); - ASSERT_EQ(0, parsed_data.times[5]); - ASSERT_EQ(1072048, parsed_data.times[6]); - ASSERT_EQ(0, parsed_data.times[7]); - - ASSERT_EQ( - "cpu_label=cpu, user=57211920, nice=335926, system=18096939, idle=2526329830," - " iOWait=14818556, irq=0, softIrq=1072048, steal=0", - parsed_data.toString()); -} - -TEST(LinuxCpuMeasurementTest, testCalculateCpuActivePercentage) -{ - auto p = computeCpuActivePercentage(proc_samples[0], proc_samples[1]); - ASSERT_DOUBLE_EQ(CPU_ACTIVE_PROC_SAMPLE_0_1, p); -} - -TEST(LinuxCpuMeasurementTest, testEmptyProcCpuData) -{ - system_metrics_collector::ProcCpuData empty; - ASSERT_EQ(system_metrics_collector::ProcCpuData::EMPTY_LABEL, empty.cpu_label); - - for (int i = 0; i < static_cast(system_metrics_collector::ProcCpuStates::kNumProcCpuStates); - i++) - { - ASSERT_EQ(0, empty.times[i]); - } + ASSERT_DOUBLE_EQ(test_constants::CPU_ACTIVE_PROC_SAMPLE_0_1, cpu_active_percentage); } TEST_F(LinuxCpuMeasurementTestFixture, testPublishMetricsMessage) @@ -328,16 +251,16 @@ TEST_F(LinuxCpuMeasurementTestFixture, testPublishMetricsMessage) ex.spin_until_future_complete(dummy_future, test_constants::TEST_DURATION); EXPECT_EQ(3, test_receive_measurements->getNumReceived()); // expectation is: - // 50 ms: proc_samples[0] is collected - // 80 ms: statistics derived from proc_samples[N/A-0] is published. statistics are cleared - // 100 ms: proc_samples[1] is collected - // 150 ms: proc_samples[2] is collected - // 160 ms: statistics derived from proc_samples[0-1 & 1-2] is published. statistics are cleared - // 200 ms: proc_samples[3] is collected - // 240 ms: statistics derived from proc_samples[2-3] is published. statistics are cleared - // 250 ms: proc_samples[4] is collected. last getStatisticsResults() is of proc_samples[3-4] + // 50 ms: PROC_SAMPLES[0] is collected + // 80 ms: statistics derived from PROC_SAMPLES[N/A-0] is published. statistics are cleared + // 100 ms: PROC_SAMPLES[1] is collected + // 150 ms: PROC_SAMPLES[2] is collected + // 160 ms: statistics derived from PROC_SAMPLES[0-1 & 1-2] is published. statistics are cleared + // 200 ms: PROC_SAMPLES[3] is collected + // 240 ms: statistics derived from PROC_SAMPLES[2-3] is published. statistics are cleared + // 250 ms: PROC_SAMPLES[4] is collected. last getStatisticsResults() is of PROC_SAMPLES[3-4] StatisticData data = test_measure_linux_cpu->getStatisticsResults(); - double expected_cpu_active = computeCpuActivePercentage(proc_samples[3], proc_samples[4]); + double expected_cpu_active = computeCpuActivePercentage(PROC_SAMPLES[3], PROC_SAMPLES[4]); EXPECT_DOUBLE_EQ(expected_cpu_active, data.average); EXPECT_DOUBLE_EQ(expected_cpu_active, data.min); EXPECT_DOUBLE_EQ(expected_cpu_active, data.max); @@ -371,16 +294,16 @@ TEST_F(LinuxCpuMeasurementTestFixture, testPublishMetricsMessage) ex.spin_until_future_complete(dummy_future, test_constants::TEST_DURATION); EXPECT_EQ(6, test_receive_measurements->getNumReceived()); // expectation is: - // 50 ms: proc_samples[5] is collected - // 80 ms: statistics derived from proc_samples[N/A-5] is published. statistics are cleared - // 100 ms: proc_samples[6] is collected - // 150 ms: proc_samples[7] is collected - // 160 ms: statistics derived from proc_samples[5-6 & 6-7] is published. statistics are cleared - // 200 ms: proc_samples[8] is collected - // 240 ms: statistics derived from proc_samples[7-8] is published. statistics are cleared - // 250 ms: proc_samples[9] is collected. last getStatisticsResults() is of proc_samples[8-9] + // 50 ms: PROC_SAMPLES[5] is collected + // 80 ms: statistics derived from PROC_SAMPLES[N/A-5] is published. statistics are cleared + // 100 ms: PROC_SAMPLES[6] is collected + // 150 ms: PROC_SAMPLES[7] is collected + // 160 ms: statistics derived from PROC_SAMPLES[5-6 & 6-7] is published. statistics are cleared + // 200 ms: PROC_SAMPLES[8] is collected + // 240 ms: statistics derived from PROC_SAMPLES[7-8] is published. statistics are cleared + // 250 ms: PROC_SAMPLES[9] is collected. last getStatisticsResults() is of PROC_SAMPLES[8-9] data = test_measure_linux_cpu->getStatisticsResults(); - expected_cpu_active = computeCpuActivePercentage(proc_samples[8], proc_samples[9]); + expected_cpu_active = computeCpuActivePercentage(PROC_SAMPLES[8], PROC_SAMPLES[9]); EXPECT_DOUBLE_EQ(expected_cpu_active, data.average); EXPECT_DOUBLE_EQ(expected_cpu_active, data.min); EXPECT_DOUBLE_EQ(expected_cpu_active, data.max); diff --git a/system_metrics_collector/test/system_metrics_collector/test_utilities.cpp b/system_metrics_collector/test/system_metrics_collector/test_utilities.cpp index b2f2c539..375124b6 100644 --- a/system_metrics_collector/test/system_metrics_collector/test_utilities.cpp +++ b/system_metrics_collector/test/system_metrics_collector/test_utilities.cpp @@ -22,8 +22,71 @@ #include "../../src/system_metrics_collector/utilities.hpp" #include "test_constants.hpp" +#include "test_utilities.hpp" -TEST(UtilitiesTest, testProcessLines) + +TEST(UtilitiesTest, testParseProcStatLine) +{ + auto parsed_data = system_metrics_collector::processStatCpuLine(test_constants::PROC_SAMPLES[0]); + + ASSERT_EQ("cpu", parsed_data.cpu_label); + ASSERT_EQ(22451232, parsed_data.times[0]); + ASSERT_EQ(118653, parsed_data.times[1]); + ASSERT_EQ(7348045, parsed_data.times[2]); + ASSERT_EQ(934943300, parsed_data.times[3]); + ASSERT_EQ(5378119, parsed_data.times[4]); + ASSERT_EQ(0, parsed_data.times[5]); + ASSERT_EQ(419114, parsed_data.times[6]); + ASSERT_EQ(0, parsed_data.times[7]); + + ASSERT_EQ( + "cpu_label=cpu, user=22451232, nice=118653, system=7348045, idle=934943300," + " iOWait=5378119, irq=0, softIrq=419114, steal=0", + parsed_data.toString()); +} + +TEST(UtilitiesTest, testParseProcStatLine2) +{ + auto parsed_data = system_metrics_collector::processStatCpuLine( + test_constants::PROC_SAMPLE_RESOLUTION_TEST); + + ASSERT_EQ("cpu", parsed_data.cpu_label); + ASSERT_EQ(57211920, parsed_data.times[0]); + ASSERT_EQ(335926, parsed_data.times[1]); + ASSERT_EQ(18096939, parsed_data.times[2]); + ASSERT_EQ(2526329830, parsed_data.times[3]); + ASSERT_EQ(14818556, parsed_data.times[4]); + ASSERT_EQ(0, parsed_data.times[5]); + ASSERT_EQ(1072048, parsed_data.times[6]); + ASSERT_EQ(0, parsed_data.times[7]); + + ASSERT_EQ( + "cpu_label=cpu, user=57211920, nice=335926, system=18096939, idle=2526329830," + " iOWait=14818556, irq=0, softIrq=1072048, steal=0", + parsed_data.toString()); +} + +TEST(UtilitiesTest, testEmptyProcCpuData) +{ + system_metrics_collector::ProcCpuData empty; + + ASSERT_EQ(system_metrics_collector::ProcCpuData::EMPTY_LABEL, empty.cpu_label); + + for (int i = 0; i < static_cast(system_metrics_collector::ProcCpuStates::kNumProcCpuStates); + i++) + { + ASSERT_EQ(0, empty.times[i]); + } +} + +TEST(UtilitiesTest, testCalculateCpuActivePercentage) +{ + auto p = test_utilities::computeCpuActivePercentage(test_constants::PROC_SAMPLES[0], + test_constants::PROC_SAMPLES[1]); + ASSERT_DOUBLE_EQ(test_constants::CPU_ACTIVE_PROC_SAMPLE_0_1, p); +} + +TEST(UtilitiesTest, testProcMemInfoLines) { auto d = system_metrics_collector::processMemInfoLines(test_constants::EMPTY_SAMPLE); ASSERT_TRUE(std::isnan(d)); diff --git a/system_metrics_collector/test/system_metrics_collector/test_utilities.hpp b/system_metrics_collector/test/system_metrics_collector/test_utilities.hpp new file mode 100644 index 00000000..808d6cea --- /dev/null +++ b/system_metrics_collector/test/system_metrics_collector/test_utilities.hpp @@ -0,0 +1,37 @@ +// Copyright 2019 Amazon.com, Inc. or its affiliates. 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. + +#ifndef SYSTEM_METRICS_COLLECTOR__TEST_UTILITIES_HPP_ +#define SYSTEM_METRICS_COLLECTOR__TEST_UTILITIES_HPP_ + +#include + +#include "../../src/system_metrics_collector/utilities.hpp" + +/** + * Constants used and shared among the various system metrics collector tests. + */ +namespace test_utilities +{ + +inline double computeCpuActivePercentage(const std::string & data1, const std::string & data2) +{ + auto parsed_data1 = system_metrics_collector::processStatCpuLine(data1); + auto parsed_data2 = system_metrics_collector::processStatCpuLine(data2); + return system_metrics_collector::computeCpuActivePercentage(parsed_data1, parsed_data2); +} + +} // namespace test_utilities + +#endif // SYSTEM_METRICS_COLLECTOR__TEST_UTILITIES_HPP_