xref: /llvm-project/libc/benchmarks/JSONTest.cpp (revision deae7e982a3b08996455e2cdfdc5062bf37895a3)
1438f7fc0SSiva Chandra Reddy //===-- JSON Tests --------------------------------------------------------===//
2438f7fc0SSiva Chandra Reddy //
3438f7fc0SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4438f7fc0SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5438f7fc0SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6438f7fc0SSiva Chandra Reddy //
7438f7fc0SSiva Chandra Reddy //===----------------------------------------------------------------------===//
8438f7fc0SSiva Chandra Reddy 
9438f7fc0SSiva Chandra Reddy #include "JSON.h"
10438f7fc0SSiva Chandra Reddy #include "LibcBenchmark.h"
11438f7fc0SSiva Chandra Reddy #include "LibcMemoryBenchmark.h"
12438f7fc0SSiva Chandra Reddy #include "llvm/Support/JSON.h"
13438f7fc0SSiva Chandra Reddy #include "llvm/Support/raw_ostream.h"
14438f7fc0SSiva Chandra Reddy #include "gmock/gmock.h"
15438f7fc0SSiva Chandra Reddy #include "gtest/gtest.h"
16438f7fc0SSiva Chandra Reddy 
17438f7fc0SSiva Chandra Reddy using testing::AllOf;
18438f7fc0SSiva Chandra Reddy using testing::ExplainMatchResult;
19438f7fc0SSiva Chandra Reddy using testing::Field;
20438f7fc0SSiva Chandra Reddy using testing::Pointwise;
21438f7fc0SSiva Chandra Reddy 
22438f7fc0SSiva Chandra Reddy namespace llvm {
23438f7fc0SSiva Chandra Reddy namespace libc_benchmarks {
24438f7fc0SSiva Chandra Reddy namespace {
25438f7fc0SSiva Chandra Reddy 
getStudy()26438f7fc0SSiva Chandra Reddy Study getStudy() {
27438f7fc0SSiva Chandra Reddy   return Study{
28*deae7e98SGuillaume Chatelet       "StudyName",
29*deae7e98SGuillaume Chatelet       Runtime{HostState{"CpuName",
30*deae7e98SGuillaume Chatelet                         123,
31*deae7e98SGuillaume Chatelet                         {CacheInfo{"A", 1, 2, 3}, CacheInfo{"B", 4, 5, 6}}},
32*deae7e98SGuillaume Chatelet               456, 789,
33*deae7e98SGuillaume Chatelet               BenchmarkOptions{std::chrono::seconds(1), std::chrono::seconds(2),
34*deae7e98SGuillaume Chatelet                                10, 100, 6, 100, 0.1, 2, BenchmarkLog::Full}},
35*deae7e98SGuillaume Chatelet       StudyConfiguration{std::string("Function"), 30U, false, 32U,
36*deae7e98SGuillaume Chatelet                          std::string("Distribution"), Align(16), 3U},
37*deae7e98SGuillaume Chatelet       {std::chrono::seconds(3), std::chrono::seconds(4)}};
38438f7fc0SSiva Chandra Reddy }
39438f7fc0SSiva Chandra Reddy 
serializeToString(const Study & S)40*deae7e98SGuillaume Chatelet static std::string serializeToString(const Study &S) {
41438f7fc0SSiva Chandra Reddy   std::string Buffer;
42438f7fc0SSiva Chandra Reddy   raw_string_ostream RSO(Buffer);
43438f7fc0SSiva Chandra Reddy   json::OStream JOS(RSO);
44*deae7e98SGuillaume Chatelet   serializeToJson(S, JOS);
45438f7fc0SSiva Chandra Reddy   return Buffer;
46438f7fc0SSiva Chandra Reddy }
47438f7fc0SSiva Chandra Reddy 
48438f7fc0SSiva Chandra Reddy MATCHER(EqualsCacheInfo, "") {
49438f7fc0SSiva Chandra Reddy   const CacheInfo &A = ::testing::get<0>(arg);
50438f7fc0SSiva Chandra Reddy   const CacheInfo &B = ::testing::get<1>(arg);
51438f7fc0SSiva Chandra Reddy   return ExplainMatchResult(AllOf(Field(&CacheInfo::Type, B.Type),
52438f7fc0SSiva Chandra Reddy                                   Field(&CacheInfo::Level, B.Level),
53438f7fc0SSiva Chandra Reddy                                   Field(&CacheInfo::Size, B.Size),
54438f7fc0SSiva Chandra Reddy                                   Field(&CacheInfo::NumSharing, B.NumSharing)),
55438f7fc0SSiva Chandra Reddy                             A, result_listener);
56438f7fc0SSiva Chandra Reddy }
57438f7fc0SSiva Chandra Reddy 
equals(const HostState & H)58*deae7e98SGuillaume Chatelet auto equals(const HostState &H) -> auto {
59438f7fc0SSiva Chandra Reddy   return AllOf(
60438f7fc0SSiva Chandra Reddy       Field(&HostState::CpuName, H.CpuName),
61438f7fc0SSiva Chandra Reddy       Field(&HostState::CpuFrequency, H.CpuFrequency),
62438f7fc0SSiva Chandra Reddy       Field(&HostState::Caches, Pointwise(EqualsCacheInfo(), H.Caches)));
63438f7fc0SSiva Chandra Reddy }
64438f7fc0SSiva Chandra Reddy 
equals(const StudyConfiguration & SC)65*deae7e98SGuillaume Chatelet auto equals(const StudyConfiguration &SC) -> auto {
66*deae7e98SGuillaume Chatelet   return AllOf(
67*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::Function, SC.Function),
68*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::NumTrials, SC.NumTrials),
69*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::IsSweepMode, SC.IsSweepMode),
70*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::SweepModeMaxSize, SC.SweepModeMaxSize),
71*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::SizeDistributionName, SC.SizeDistributionName),
72*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::AccessAlignment, SC.AccessAlignment),
73*deae7e98SGuillaume Chatelet       Field(&StudyConfiguration::MemcmpMismatchAt, SC.MemcmpMismatchAt));
74*deae7e98SGuillaume Chatelet }
75*deae7e98SGuillaume Chatelet 
equals(const BenchmarkOptions & BO)76*deae7e98SGuillaume Chatelet auto equals(const BenchmarkOptions &BO) -> auto {
77438f7fc0SSiva Chandra Reddy   return AllOf(
78438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::MinDuration, BO.MinDuration),
79438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::MaxDuration, BO.MaxDuration),
80438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::InitialIterations, BO.InitialIterations),
81438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::MaxIterations, BO.MaxIterations),
82438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::MinSamples, BO.MinSamples),
83438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::MaxSamples, BO.MaxSamples),
84438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::Epsilon, BO.Epsilon),
85438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::ScalingFactor, BO.ScalingFactor),
86438f7fc0SSiva Chandra Reddy       Field(&BenchmarkOptions::Log, BO.Log));
87438f7fc0SSiva Chandra Reddy }
88438f7fc0SSiva Chandra Reddy 
equals(const Runtime & RI)89*deae7e98SGuillaume Chatelet auto equals(const Runtime &RI) -> auto {
90*deae7e98SGuillaume Chatelet   return AllOf(Field(&Runtime::Host, equals(RI.Host)),
91*deae7e98SGuillaume Chatelet                Field(&Runtime::BufferSize, RI.BufferSize),
92*deae7e98SGuillaume Chatelet                Field(&Runtime::BatchParameterCount, RI.BatchParameterCount),
93*deae7e98SGuillaume Chatelet                Field(&Runtime::BenchmarkOptions, equals(RI.BenchmarkOptions)));
94438f7fc0SSiva Chandra Reddy }
95438f7fc0SSiva Chandra Reddy 
equals(const Study & S)96*deae7e98SGuillaume Chatelet auto equals(const Study &S) -> auto {
97*deae7e98SGuillaume Chatelet   return AllOf(Field(&Study::StudyName, S.StudyName),
98*deae7e98SGuillaume Chatelet                Field(&Study::Runtime, equals(S.Runtime)),
99*deae7e98SGuillaume Chatelet                Field(&Study::Configuration, equals(S.Configuration)),
100*deae7e98SGuillaume Chatelet                Field(&Study::Measurements, S.Measurements));
101438f7fc0SSiva Chandra Reddy }
102438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,RoundTrip)103438f7fc0SSiva Chandra Reddy TEST(JsonTest, RoundTrip) {
104438f7fc0SSiva Chandra Reddy   const Study S = getStudy();
105*deae7e98SGuillaume Chatelet   const auto Serialized = serializeToString(S);
106*deae7e98SGuillaume Chatelet   auto StudyOrError = parseJsonStudy(Serialized);
107438f7fc0SSiva Chandra Reddy   if (auto Err = StudyOrError.takeError())
108*deae7e98SGuillaume Chatelet     EXPECT_FALSE(Err) << "Unexpected error : " << Err << "\n" << Serialized;
109438f7fc0SSiva Chandra Reddy   const Study &Parsed = *StudyOrError;
110*deae7e98SGuillaume Chatelet   EXPECT_THAT(Parsed, equals(S)) << Serialized << "\n"
111*deae7e98SGuillaume Chatelet                                  << serializeToString(Parsed);
112438f7fc0SSiva Chandra Reddy }
113438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,SupplementaryField)114438f7fc0SSiva Chandra Reddy TEST(JsonTest, SupplementaryField) {
115*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
116438f7fc0SSiva Chandra Reddy       "UnknownField": 10
117438f7fc0SSiva Chandra Reddy     }
118438f7fc0SSiva Chandra Reddy   )");
119438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()), "Unknown field: UnknownField");
120438f7fc0SSiva Chandra Reddy }
121438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidType)122438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidType) {
123*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
124*deae7e98SGuillaume Chatelet       "Runtime": 1
125438f7fc0SSiva Chandra Reddy     }
126438f7fc0SSiva Chandra Reddy   )");
127438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()), "Expected JSON Object");
128438f7fc0SSiva Chandra Reddy }
129438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidDuration)130438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidDuration) {
131*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
132*deae7e98SGuillaume Chatelet       "Runtime": {
133*deae7e98SGuillaume Chatelet         "BenchmarkOptions": {
134438f7fc0SSiva Chandra Reddy           "MinDuration": "Duration should be a Number"
135438f7fc0SSiva Chandra Reddy         }
136438f7fc0SSiva Chandra Reddy       }
137*deae7e98SGuillaume Chatelet     }
138438f7fc0SSiva Chandra Reddy   )");
139438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()), "Can't parse Duration");
140438f7fc0SSiva Chandra Reddy }
141438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidAlignType)142438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidAlignType) {
143*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
144438f7fc0SSiva Chandra Reddy       "Configuration": {
145*deae7e98SGuillaume Chatelet         "AccessAlignment": "Align should be an Integer"
146438f7fc0SSiva Chandra Reddy       }
147438f7fc0SSiva Chandra Reddy     }
148438f7fc0SSiva Chandra Reddy   )");
149438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()), "Can't parse Align, not an Integer");
150438f7fc0SSiva Chandra Reddy }
151438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidAlign)152438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidAlign) {
153*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
154438f7fc0SSiva Chandra Reddy       "Configuration": {
155*deae7e98SGuillaume Chatelet         "AccessAlignment": 3
156438f7fc0SSiva Chandra Reddy       }
157438f7fc0SSiva Chandra Reddy     }
158438f7fc0SSiva Chandra Reddy   )");
159438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()),
160438f7fc0SSiva Chandra Reddy             "Can't parse Align, not a power of two");
161438f7fc0SSiva Chandra Reddy }
162438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidBenchmarkLogType)163438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidBenchmarkLogType) {
164*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
165*deae7e98SGuillaume Chatelet       "Runtime": {
166*deae7e98SGuillaume Chatelet         "BenchmarkOptions":{
167438f7fc0SSiva Chandra Reddy           "Log": 3
168438f7fc0SSiva Chandra Reddy         }
169438f7fc0SSiva Chandra Reddy       }
170*deae7e98SGuillaume Chatelet     }
171438f7fc0SSiva Chandra Reddy   )");
172438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()),
173438f7fc0SSiva Chandra Reddy             "Can't parse BenchmarkLog, not a String");
174438f7fc0SSiva Chandra Reddy }
175438f7fc0SSiva Chandra Reddy 
TEST(JsonTest,InvalidBenchmarkLog)176438f7fc0SSiva Chandra Reddy TEST(JsonTest, InvalidBenchmarkLog) {
177*deae7e98SGuillaume Chatelet   auto Failure = parseJsonStudy(R"({
178*deae7e98SGuillaume Chatelet       "Runtime": {
179*deae7e98SGuillaume Chatelet         "BenchmarkOptions":{
180438f7fc0SSiva Chandra Reddy           "Log": "Unknown"
181438f7fc0SSiva Chandra Reddy         }
182438f7fc0SSiva Chandra Reddy       }
183*deae7e98SGuillaume Chatelet     }
184438f7fc0SSiva Chandra Reddy   )");
185438f7fc0SSiva Chandra Reddy   EXPECT_EQ(toString(Failure.takeError()),
186438f7fc0SSiva Chandra Reddy             "Can't parse BenchmarkLog, invalid value 'Unknown'");
187438f7fc0SSiva Chandra Reddy }
188438f7fc0SSiva Chandra Reddy 
189438f7fc0SSiva Chandra Reddy } // namespace
190438f7fc0SSiva Chandra Reddy } // namespace libc_benchmarks
191438f7fc0SSiva Chandra Reddy } // namespace llvm
192