207
|
1 //===-- JSON Tests --------------------------------------------------------===//
|
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #include "JSON.h"
|
|
10 #include "LibcBenchmark.h"
|
|
11 #include "LibcMemoryBenchmark.h"
|
|
12 #include "llvm/Support/JSON.h"
|
|
13 #include "llvm/Support/raw_ostream.h"
|
|
14 #include "gmock/gmock.h"
|
|
15 #include "gtest/gtest.h"
|
|
16
|
|
17 using testing::AllOf;
|
|
18 using testing::ExplainMatchResult;
|
|
19 using testing::Field;
|
|
20 using testing::Pointwise;
|
|
21
|
|
22 namespace llvm {
|
|
23 namespace libc_benchmarks {
|
|
24 namespace {
|
|
25
|
|
26 Study getStudy() {
|
|
27 return Study{
|
|
28 "StudyName",
|
|
29 Runtime{HostState{"CpuName",
|
|
30 123,
|
|
31 {CacheInfo{"A", 1, 2, 3}, CacheInfo{"B", 4, 5, 6}}},
|
|
32 456, 789,
|
|
33 BenchmarkOptions{std::chrono::seconds(1), std::chrono::seconds(2),
|
|
34 10, 100, 6, 100, 0.1, 2, BenchmarkLog::Full}},
|
|
35 StudyConfiguration{std::string("Function"), 30U, false, 32U,
|
|
36 std::string("Distribution"), Align(16), 3U},
|
|
37 {std::chrono::seconds(3), std::chrono::seconds(4)}};
|
|
38 }
|
|
39
|
|
40 static std::string serializeToString(const Study &S) {
|
|
41 std::string Buffer;
|
|
42 raw_string_ostream RSO(Buffer);
|
|
43 json::OStream JOS(RSO);
|
|
44 serializeToJson(S, JOS);
|
|
45 return Buffer;
|
|
46 }
|
|
47
|
|
48 MATCHER(EqualsCacheInfo, "") {
|
|
49 const CacheInfo &A = ::testing::get<0>(arg);
|
|
50 const CacheInfo &B = ::testing::get<1>(arg);
|
|
51 return ExplainMatchResult(AllOf(Field(&CacheInfo::Type, B.Type),
|
|
52 Field(&CacheInfo::Level, B.Level),
|
|
53 Field(&CacheInfo::Size, B.Size),
|
|
54 Field(&CacheInfo::NumSharing, B.NumSharing)),
|
|
55 A, result_listener);
|
|
56 }
|
|
57
|
|
58 auto equals(const HostState &H) -> auto {
|
|
59 return AllOf(
|
|
60 Field(&HostState::CpuName, H.CpuName),
|
|
61 Field(&HostState::CpuFrequency, H.CpuFrequency),
|
|
62 Field(&HostState::Caches, Pointwise(EqualsCacheInfo(), H.Caches)));
|
|
63 }
|
|
64
|
|
65 auto equals(const StudyConfiguration &SC) -> auto {
|
|
66 return AllOf(
|
|
67 Field(&StudyConfiguration::Function, SC.Function),
|
|
68 Field(&StudyConfiguration::NumTrials, SC.NumTrials),
|
|
69 Field(&StudyConfiguration::IsSweepMode, SC.IsSweepMode),
|
|
70 Field(&StudyConfiguration::SweepModeMaxSize, SC.SweepModeMaxSize),
|
|
71 Field(&StudyConfiguration::SizeDistributionName, SC.SizeDistributionName),
|
|
72 Field(&StudyConfiguration::AccessAlignment, SC.AccessAlignment),
|
|
73 Field(&StudyConfiguration::MemcmpMismatchAt, SC.MemcmpMismatchAt));
|
|
74 }
|
|
75
|
|
76 auto equals(const BenchmarkOptions &BO) -> auto {
|
|
77 return AllOf(
|
|
78 Field(&BenchmarkOptions::MinDuration, BO.MinDuration),
|
|
79 Field(&BenchmarkOptions::MaxDuration, BO.MaxDuration),
|
|
80 Field(&BenchmarkOptions::InitialIterations, BO.InitialIterations),
|
|
81 Field(&BenchmarkOptions::MaxIterations, BO.MaxIterations),
|
|
82 Field(&BenchmarkOptions::MinSamples, BO.MinSamples),
|
|
83 Field(&BenchmarkOptions::MaxSamples, BO.MaxSamples),
|
|
84 Field(&BenchmarkOptions::Epsilon, BO.Epsilon),
|
|
85 Field(&BenchmarkOptions::ScalingFactor, BO.ScalingFactor),
|
|
86 Field(&BenchmarkOptions::Log, BO.Log));
|
|
87 }
|
|
88
|
|
89 auto equals(const Runtime &RI) -> auto {
|
|
90 return AllOf(Field(&Runtime::Host, equals(RI.Host)),
|
|
91 Field(&Runtime::BufferSize, RI.BufferSize),
|
|
92 Field(&Runtime::BatchParameterCount, RI.BatchParameterCount),
|
|
93 Field(&Runtime::BenchmarkOptions, equals(RI.BenchmarkOptions)));
|
|
94 }
|
|
95
|
|
96 auto equals(const Study &S) -> auto {
|
|
97 return AllOf(Field(&Study::StudyName, S.StudyName),
|
|
98 Field(&Study::Runtime, equals(S.Runtime)),
|
|
99 Field(&Study::Configuration, equals(S.Configuration)),
|
|
100 Field(&Study::Measurements, S.Measurements));
|
|
101 }
|
|
102
|
|
103 TEST(JsonTest, RoundTrip) {
|
|
104 const Study S = getStudy();
|
|
105 const auto Serialized = serializeToString(S);
|
|
106 auto StudyOrError = parseJsonStudy(Serialized);
|
|
107 if (auto Err = StudyOrError.takeError())
|
|
108 EXPECT_FALSE(Err) << "Unexpected error : " << Err << "\n" << Serialized;
|
|
109 const Study &Parsed = *StudyOrError;
|
|
110 EXPECT_THAT(Parsed, equals(S)) << Serialized << "\n"
|
|
111 << serializeToString(Parsed);
|
|
112 }
|
|
113
|
|
114 TEST(JsonTest, SupplementaryField) {
|
|
115 auto Failure = parseJsonStudy(R"({
|
|
116 "UnknownField": 10
|
|
117 }
|
|
118 )");
|
|
119 EXPECT_EQ(toString(Failure.takeError()), "Unknown field: UnknownField");
|
|
120 }
|
|
121
|
|
122 TEST(JsonTest, InvalidType) {
|
|
123 auto Failure = parseJsonStudy(R"({
|
|
124 "Runtime": 1
|
|
125 }
|
|
126 )");
|
|
127 EXPECT_EQ(toString(Failure.takeError()), "Expected JSON Object");
|
|
128 }
|
|
129
|
|
130 TEST(JsonTest, InvalidDuration) {
|
|
131 auto Failure = parseJsonStudy(R"({
|
|
132 "Runtime": {
|
|
133 "BenchmarkOptions": {
|
|
134 "MinDuration": "Duration should be a Number"
|
|
135 }
|
|
136 }
|
|
137 }
|
|
138 )");
|
|
139 EXPECT_EQ(toString(Failure.takeError()), "Can't parse Duration");
|
|
140 }
|
|
141
|
|
142 TEST(JsonTest, InvalidAlignType) {
|
|
143 auto Failure = parseJsonStudy(R"({
|
|
144 "Configuration": {
|
|
145 "AccessAlignment": "Align should be an Integer"
|
|
146 }
|
|
147 }
|
|
148 )");
|
|
149 EXPECT_EQ(toString(Failure.takeError()), "Can't parse Align, not an Integer");
|
|
150 }
|
|
151
|
|
152 TEST(JsonTest, InvalidAlign) {
|
|
153 auto Failure = parseJsonStudy(R"({
|
|
154 "Configuration": {
|
|
155 "AccessAlignment": 3
|
|
156 }
|
|
157 }
|
|
158 )");
|
|
159 EXPECT_EQ(toString(Failure.takeError()),
|
|
160 "Can't parse Align, not a power of two");
|
|
161 }
|
|
162
|
|
163 TEST(JsonTest, InvalidBenchmarkLogType) {
|
|
164 auto Failure = parseJsonStudy(R"({
|
|
165 "Runtime": {
|
|
166 "BenchmarkOptions":{
|
|
167 "Log": 3
|
|
168 }
|
|
169 }
|
|
170 }
|
|
171 )");
|
|
172 EXPECT_EQ(toString(Failure.takeError()),
|
|
173 "Can't parse BenchmarkLog, not a String");
|
|
174 }
|
|
175
|
|
176 TEST(JsonTest, InvalidBenchmarkLog) {
|
|
177 auto Failure = parseJsonStudy(R"({
|
|
178 "Runtime": {
|
|
179 "BenchmarkOptions":{
|
|
180 "Log": "Unknown"
|
|
181 }
|
|
182 }
|
|
183 }
|
|
184 )");
|
|
185 EXPECT_EQ(toString(Failure.takeError()),
|
|
186 "Can't parse BenchmarkLog, invalid value 'Unknown'");
|
|
187 }
|
|
188
|
|
189 } // namespace
|
|
190 } // namespace libc_benchmarks
|
|
191 } // namespace llvm
|