Jlm
Loading...
Searching...
No Matches
StatisticsTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
9
10#include <atomic>
11#include <fstream>
12#include <memory>
13
15{
16public:
18 : jlm::util::Statistics(id, sourceFile)
19 {}
20
21 void
22 Start(uint64_t count, double weight)
23 {
24 AddMeasurement("count", count);
25 AddMeasurement("weight", weight);
26 AddTimer("Timer").start();
27 }
28
29 void
30 Stop(int64_t bankAccount, std::string state)
31 {
32 AddMeasurement("bankAccount", bankAccount);
33 AddMeasurement("state", std::move(state));
34 GetTimer("Timer").stop();
35 }
36};
37
38TEST(StatisticsTests, TestStatisticsMeasurements)
39{
40 using namespace jlm::util;
41
42 // Arrange
43 FilePath path("file.ll");
44 MyTestStatistics statistics(Statistics::Id::Aggregation, path);
45
46 // Act
47 statistics.Start(10, 6.0);
48 // Pretend to do real work
49 std::atomic_signal_fence(std::memory_order::memory_order_seq_cst);
50 statistics.Stop(-400, "poor");
51
52 // Assert
53 EXPECT_EQ(statistics.GetId(), Statistics::Id::Aggregation);
54 EXPECT_EQ(statistics.GetSourceFile(), path);
55
56 EXPECT_TRUE(statistics.HasMeasurement("count"));
57 EXPECT_FALSE(statistics.HasMeasurement("height"));
58 EXPECT_TRUE(statistics.HasTimer("Timer"));
59 EXPECT_FALSE(statistics.HasTimer("SpinLockTimer"));
60
61 EXPECT_EQ(statistics.GetMeasurementValue<uint64_t>("count"), 10u);
62 EXPECT_EQ(statistics.GetMeasurementValue<double>("weight"), 6.0);
63 EXPECT_EQ(statistics.GetMeasurementValue<int64_t>("bankAccount"), -400);
64 EXPECT_EQ(statistics.GetMeasurementValue<std::string>("state"), "poor");
65 EXPECT_GT(statistics.GetTimerElapsedNanoseconds("Timer"), 0u);
66
67 // Ensure order is preserved
68 auto measurements = statistics.GetMeasurements();
69 auto it = measurements.begin();
70 EXPECT_EQ(it->first, "count");
71 it++;
72 EXPECT_EQ(it->first, "weight");
73 it++;
74 EXPECT_EQ(it->first, "bankAccount");
75 it++;
76 EXPECT_EQ(it->first, "state");
77 it++;
78 EXPECT_EQ(it, measurements.end());
79
80 auto timers = statistics.GetTimers();
81 EXPECT_EQ(timers.begin()->first, "Timer");
82}
83
84TEST(StatisticsTests, TestStatisticsCollection)
85{
86 using namespace jlm::util;
87
88 // Arrange
89 StatisticsCollectorSettings settings({ Statistics::Id::Aggregation });
90 StatisticsCollector collector(std::move(settings));
91
92 FilePath path("file.ll");
93 std::unique_ptr<Statistics> testStatistics1(
94 new MyTestStatistics(Statistics::Id::Aggregation, path));
95 std::unique_ptr<Statistics> testStatistics2(
96 new MyTestStatistics(Statistics::Id::LoopUnrolling, path));
97
98 // Act
99 collector.CollectDemandedStatistics(std::move(testStatistics1));
100 collector.CollectDemandedStatistics(std::move(testStatistics2));
101
102 // Assert
103 auto numCollectedStatistics =
104 std::distance(collector.CollectedStatistics().begin(), collector.CollectedStatistics().end());
105
106 EXPECT_EQ(numCollectedStatistics, 1u);
107 for (auto & statistic : collector.CollectedStatistics())
108 {
109 EXPECT_EQ(statistic.GetId(), Statistics::Id::Aggregation);
110 }
111}
112
113TEST(StatisticsTests, TestStatisticsPrinting)
114{
115 using namespace jlm::util;
116
117 // Arrange
118 auto testOutputDir = FilePath::TempDirectoryPath().Join("jlm-test-statistics");
119
120 // Remove the output dir if it was not properly cleaned up last time
121 std::filesystem::remove(testOutputDir.to_str());
122 EXPECT_FALSE(testOutputDir.Exists());
123
125 { Statistics::Id::Aggregation },
126 testOutputDir,
127 "test-module");
128
129 StatisticsCollector collector(settings);
130
131 FilePath path("file.ll");
132 std::unique_ptr<MyTestStatistics> statistics(
133 new MyTestStatistics(Statistics::Id::Aggregation, path));
134 statistics->Start(10, 6.0);
135 statistics->Stop(-400, "poor");
136
137 collector.CollectDemandedStatistics(std::move(statistics));
138
139 // Act
140 collector.PrintStatistics();
141
142 // Assert
143 EXPECT_TRUE(testOutputDir.IsDirectory());
144
145 const auto outputFileName = "test-module-" + settings.GetUniqueString() + "-statistics.log";
146 std::ifstream file(testOutputDir.Join(outputFileName).to_str());
147 std::string name, fileName, measurement;
148 file >> name >> fileName >> measurement;
149
150 EXPECT_EQ(name, "Aggregation");
151 EXPECT_EQ(fileName, path.to_str());
152 EXPECT_EQ(measurement, "count:10");
153
154 // Cleanup
155 std::filesystem::remove_all(testOutputDir.to_str());
156}
157
158TEST(StatisticsTests, TestCreateOutputFile)
159{
160 using namespace jlm::util;
161
162 // Arrange
164 { Statistics::Id::Aggregation },
165 FilePath("/tmp"),
166 "test-module");
167 settings.SetUniqueString("ABC");
168 StatisticsCollector collector(std::move(settings));
169
170 // Act
171 const auto statsFile = collector.createOutputFile("stats.log");
172
173 const auto cool0 = collector.createOutputFile("cool", true);
174 const auto cool1 = collector.createOutputFile("cool", true);
175
176 const auto nice0 = collector.createOutputFile("nice.txt", true);
177 const auto nice1 = collector.createOutputFile("nice.txt", true);
178
179 // Assert
180 EXPECT_EQ(statsFile.path(), "/tmp/test-module-ABC-stats.log");
181
182 EXPECT_EQ(cool0.path(), "/tmp/test-module-ABC-cool-0");
183 EXPECT_EQ(cool1.path(), "/tmp/test-module-ABC-cool-1");
184
185 EXPECT_EQ(nice0.path(), "/tmp/test-module-ABC-nice-0.txt");
186 EXPECT_EQ(nice1.path(), "/tmp/test-module-ABC-nice-1.txt");
187}
TEST(StatisticsTests, TestStatisticsMeasurements)
void Stop(int64_t bankAccount, std::string state)
MyTestStatistics(jlm::util::Statistics::Id id, const jlm::util::FilePath &sourceFile)
void Start(uint64_t count, double weight)
const std::string & to_str() const noexcept
Definition file.hpp:275
void SetUniqueString(std::string uniqueString)
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
Statistics Interface.
util::Timer & GetTimer(const std::string &name)
const util::FilePath & GetSourceFile() const
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
bool HasTimer(const std::string &name) const noexcept
util::Timer & AddTimer(std::string name)
const T & GetMeasurementValue(const std::string &name) const
IteratorRange< MeasurementList::const_iterator > GetMeasurements() const
IteratorRange< TimerList::const_iterator > GetTimers() const
size_t GetTimerElapsedNanoseconds(const std::string &name) const
bool HasMeasurement(const std::string &name) const noexcept
Statistics::Id GetId() const noexcept
void AddMeasurement(std::string name, T value)
void start() noexcept
Definition time.hpp:54
void stop() noexcept
Definition time.hpp:67