blob: a0ef26ee87d764a16063188e2c2cb361ba09e86b [file] [log] [blame]
Paula Toth66d00fe2020-04-08 17:16:301//===-- 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
Guillaume Chateletaba80d02020-01-06 12:17:049#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
17using testing::AllOf;
18using testing::ExplainMatchResult;
19using testing::Field;
20using testing::Pointwise;
21
22namespace llvm {
23namespace libc_benchmarks {
24namespace {
25
26Study getStudy() {
27 return Study{
Guillaume Chateletdeae7e92020-12-17 13:16:1428 "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)}};
Guillaume Chateletaba80d02020-01-06 12:17:0438}
39
Guillaume Chateletdeae7e92020-12-17 13:16:1440static std::string serializeToString(const Study &S) {
Guillaume Chateletaba80d02020-01-06 12:17:0441 std::string Buffer;
42 raw_string_ostream RSO(Buffer);
43 json::OStream JOS(RSO);
Guillaume Chateletdeae7e92020-12-17 13:16:1444 serializeToJson(S, JOS);
Guillaume Chateletaba80d02020-01-06 12:17:0445 return Buffer;
46}
47
48MATCHER(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
Guillaume Chateletdeae7e92020-12-17 13:16:1458auto equals(const HostState &H) -> auto {
Guillaume Chateletaba80d02020-01-06 12:17:0459 return AllOf(
60 Field(&HostState::CpuName, H.CpuName),
61 Field(&HostState::CpuFrequency, H.CpuFrequency),
62 Field(&HostState::Caches, Pointwise(EqualsCacheInfo(), H.Caches)));
63}
64
Guillaume Chateletdeae7e92020-12-17 13:16:1465auto 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
76auto equals(const BenchmarkOptions &BO) -> auto {
Guillaume Chateletaba80d02020-01-06 12:17:0477 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
Guillaume Chateletdeae7e92020-12-17 13:16:1489auto 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)));
Guillaume Chateletaba80d02020-01-06 12:17:0494}
95
Guillaume Chateletdeae7e92020-12-17 13:16:1496auto 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));
Guillaume Chateletaba80d02020-01-06 12:17:04101}
102
103TEST(JsonTest, RoundTrip) {
104 const Study S = getStudy();
Guillaume Chateletdeae7e92020-12-17 13:16:14105 const auto Serialized = serializeToString(S);
106 auto StudyOrError = parseJsonStudy(Serialized);
Guillaume Chateletaba80d02020-01-06 12:17:04107 if (auto Err = StudyOrError.takeError())
Guillaume Chateletdeae7e92020-12-17 13:16:14108 EXPECT_FALSE(Err) << "Unexpected error : " << Err << "\n" << Serialized;
Guillaume Chateletaba80d02020-01-06 12:17:04109 const Study &Parsed = *StudyOrError;
Guillaume Chateletdeae7e92020-12-17 13:16:14110 EXPECT_THAT(Parsed, equals(S)) << Serialized << "\n"
111 << serializeToString(Parsed);
Guillaume Chateletaba80d02020-01-06 12:17:04112}
113
114TEST(JsonTest, SupplementaryField) {
Guillaume Chateletdeae7e92020-12-17 13:16:14115 auto Failure = parseJsonStudy(R"({
Guillaume Chateletaba80d02020-01-06 12:17:04116 "UnknownField": 10
117 }
118 )");
119 EXPECT_EQ(toString(Failure.takeError()), "Unknown field: UnknownField");
120}
121
122TEST(JsonTest, InvalidType) {
Guillaume Chateletdeae7e92020-12-17 13:16:14123 auto Failure = parseJsonStudy(R"({
124 "Runtime": 1
Guillaume Chateletaba80d02020-01-06 12:17:04125 }
126 )");
127 EXPECT_EQ(toString(Failure.takeError()), "Expected JSON Object");
128}
129
130TEST(JsonTest, InvalidDuration) {
Guillaume Chateletdeae7e92020-12-17 13:16:14131 auto Failure = parseJsonStudy(R"({
132 "Runtime": {
133 "BenchmarkOptions": {
134 "MinDuration": "Duration should be a Number"
135 }
Guillaume Chateletaba80d02020-01-06 12:17:04136 }
137 }
138 )");
139 EXPECT_EQ(toString(Failure.takeError()), "Can't parse Duration");
140}
141
142TEST(JsonTest, InvalidAlignType) {
Guillaume Chateletdeae7e92020-12-17 13:16:14143 auto Failure = parseJsonStudy(R"({
144 "Configuration": {
145 "AccessAlignment": "Align should be an Integer"
Guillaume Chateletaba80d02020-01-06 12:17:04146 }
147 }
148 )");
149 EXPECT_EQ(toString(Failure.takeError()), "Can't parse Align, not an Integer");
150}
151
152TEST(JsonTest, InvalidAlign) {
Guillaume Chateletdeae7e92020-12-17 13:16:14153 auto Failure = parseJsonStudy(R"({
154 "Configuration": {
155 "AccessAlignment": 3
Guillaume Chateletaba80d02020-01-06 12:17:04156 }
157 }
158 )");
159 EXPECT_EQ(toString(Failure.takeError()),
160 "Can't parse Align, not a power of two");
161}
162
163TEST(JsonTest, InvalidBenchmarkLogType) {
Guillaume Chateletdeae7e92020-12-17 13:16:14164 auto Failure = parseJsonStudy(R"({
165 "Runtime": {
166 "BenchmarkOptions":{
167 "Log": 3
168 }
Guillaume Chateletaba80d02020-01-06 12:17:04169 }
170 }
171 )");
172 EXPECT_EQ(toString(Failure.takeError()),
173 "Can't parse BenchmarkLog, not a String");
174}
175
176TEST(JsonTest, InvalidBenchmarkLog) {
Guillaume Chateletdeae7e92020-12-17 13:16:14177 auto Failure = parseJsonStudy(R"({
178 "Runtime": {
179 "BenchmarkOptions":{
180 "Log": "Unknown"
181 }
Guillaume Chateletaba80d02020-01-06 12:17:04182 }
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