192 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- JSON Tests --------------------------------------------------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "JSON.h"
 | 
						|
#include "LibcBenchmark.h"
 | 
						|
#include "LibcMemoryBenchmark.h"
 | 
						|
#include "llvm/Support/JSON.h"
 | 
						|
#include "llvm/Support/raw_ostream.h"
 | 
						|
#include "gmock/gmock.h"
 | 
						|
#include "gtest/gtest.h"
 | 
						|
 | 
						|
using testing::AllOf;
 | 
						|
using testing::ExplainMatchResult;
 | 
						|
using testing::Field;
 | 
						|
using testing::Pointwise;
 | 
						|
 | 
						|
namespace llvm {
 | 
						|
namespace libc_benchmarks {
 | 
						|
namespace {
 | 
						|
 | 
						|
Study getStudy() {
 | 
						|
  return Study{
 | 
						|
      "StudyName",
 | 
						|
      Runtime{HostState{"CpuName",
 | 
						|
                        123,
 | 
						|
                        {CacheInfo{"A", 1, 2, 3}, CacheInfo{"B", 4, 5, 6}}},
 | 
						|
              456, 789,
 | 
						|
              BenchmarkOptions{std::chrono::seconds(1), std::chrono::seconds(2),
 | 
						|
                               10, 100, 6, 100, 0.1, 2, BenchmarkLog::Full}},
 | 
						|
      StudyConfiguration{std::string("Function"), 30U, false, 32U,
 | 
						|
                         std::string("Distribution"), Align(16), 3U},
 | 
						|
      {std::chrono::seconds(3), std::chrono::seconds(4)}};
 | 
						|
}
 | 
						|
 | 
						|
static std::string serializeToString(const Study &S) {
 | 
						|
  std::string Buffer;
 | 
						|
  raw_string_ostream RSO(Buffer);
 | 
						|
  json::OStream JOS(RSO);
 | 
						|
  serializeToJson(S, JOS);
 | 
						|
  return Buffer;
 | 
						|
}
 | 
						|
 | 
						|
MATCHER(EqualsCacheInfo, "") {
 | 
						|
  const CacheInfo &A = ::testing::get<0>(arg);
 | 
						|
  const CacheInfo &B = ::testing::get<1>(arg);
 | 
						|
  return ExplainMatchResult(AllOf(Field(&CacheInfo::Type, B.Type),
 | 
						|
                                  Field(&CacheInfo::Level, B.Level),
 | 
						|
                                  Field(&CacheInfo::Size, B.Size),
 | 
						|
                                  Field(&CacheInfo::NumSharing, B.NumSharing)),
 | 
						|
                            A, result_listener);
 | 
						|
}
 | 
						|
 | 
						|
auto equals(const HostState &H) -> auto {
 | 
						|
  return AllOf(
 | 
						|
      Field(&HostState::CpuName, H.CpuName),
 | 
						|
      Field(&HostState::CpuFrequency, H.CpuFrequency),
 | 
						|
      Field(&HostState::Caches, Pointwise(EqualsCacheInfo(), H.Caches)));
 | 
						|
}
 | 
						|
 | 
						|
auto equals(const StudyConfiguration &SC) -> auto {
 | 
						|
  return AllOf(
 | 
						|
      Field(&StudyConfiguration::Function, SC.Function),
 | 
						|
      Field(&StudyConfiguration::NumTrials, SC.NumTrials),
 | 
						|
      Field(&StudyConfiguration::IsSweepMode, SC.IsSweepMode),
 | 
						|
      Field(&StudyConfiguration::SweepModeMaxSize, SC.SweepModeMaxSize),
 | 
						|
      Field(&StudyConfiguration::SizeDistributionName, SC.SizeDistributionName),
 | 
						|
      Field(&StudyConfiguration::AccessAlignment, SC.AccessAlignment),
 | 
						|
      Field(&StudyConfiguration::MemcmpMismatchAt, SC.MemcmpMismatchAt));
 | 
						|
}
 | 
						|
 | 
						|
auto equals(const BenchmarkOptions &BO) -> auto {
 | 
						|
  return AllOf(
 | 
						|
      Field(&BenchmarkOptions::MinDuration, BO.MinDuration),
 | 
						|
      Field(&BenchmarkOptions::MaxDuration, BO.MaxDuration),
 | 
						|
      Field(&BenchmarkOptions::InitialIterations, BO.InitialIterations),
 | 
						|
      Field(&BenchmarkOptions::MaxIterations, BO.MaxIterations),
 | 
						|
      Field(&BenchmarkOptions::MinSamples, BO.MinSamples),
 | 
						|
      Field(&BenchmarkOptions::MaxSamples, BO.MaxSamples),
 | 
						|
      Field(&BenchmarkOptions::Epsilon, BO.Epsilon),
 | 
						|
      Field(&BenchmarkOptions::ScalingFactor, BO.ScalingFactor),
 | 
						|
      Field(&BenchmarkOptions::Log, BO.Log));
 | 
						|
}
 | 
						|
 | 
						|
auto equals(const Runtime &RI) -> auto {
 | 
						|
  return AllOf(Field(&Runtime::Host, equals(RI.Host)),
 | 
						|
               Field(&Runtime::BufferSize, RI.BufferSize),
 | 
						|
               Field(&Runtime::BatchParameterCount, RI.BatchParameterCount),
 | 
						|
               Field(&Runtime::BenchmarkOptions, equals(RI.BenchmarkOptions)));
 | 
						|
}
 | 
						|
 | 
						|
auto equals(const Study &S) -> auto {
 | 
						|
  return AllOf(Field(&Study::StudyName, S.StudyName),
 | 
						|
               Field(&Study::Runtime, equals(S.Runtime)),
 | 
						|
               Field(&Study::Configuration, equals(S.Configuration)),
 | 
						|
               Field(&Study::Measurements, S.Measurements));
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, RoundTrip) {
 | 
						|
  const Study S = getStudy();
 | 
						|
  const auto Serialized = serializeToString(S);
 | 
						|
  auto StudyOrError = parseJsonStudy(Serialized);
 | 
						|
  if (auto Err = StudyOrError.takeError())
 | 
						|
    EXPECT_FALSE(Err) << "Unexpected error : " << Err << "\n" << Serialized;
 | 
						|
  const Study &Parsed = *StudyOrError;
 | 
						|
  EXPECT_THAT(Parsed, equals(S)) << Serialized << "\n"
 | 
						|
                                 << serializeToString(Parsed);
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, SupplementaryField) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "UnknownField": 10
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()), "Unknown field: UnknownField");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidType) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Runtime": 1
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()), "Expected JSON Object");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidDuration) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Runtime": {
 | 
						|
        "BenchmarkOptions": {
 | 
						|
          "MinDuration": "Duration should be a Number"
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()), "Can't parse Duration");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidAlignType) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Configuration": {
 | 
						|
        "AccessAlignment": "Align should be an Integer"
 | 
						|
      }
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()), "Can't parse Align, not an Integer");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidAlign) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Configuration": {
 | 
						|
        "AccessAlignment": 3
 | 
						|
      }
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()),
 | 
						|
            "Can't parse Align, not a power of two");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidBenchmarkLogType) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Runtime": {
 | 
						|
        "BenchmarkOptions":{
 | 
						|
          "Log": 3
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()),
 | 
						|
            "Can't parse BenchmarkLog, not a String");
 | 
						|
}
 | 
						|
 | 
						|
TEST(JsonTest, InvalidBenchmarkLog) {
 | 
						|
  auto Failure = parseJsonStudy(R"({
 | 
						|
      "Runtime": {
 | 
						|
        "BenchmarkOptions":{
 | 
						|
          "Log": "Unknown"
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  EXPECT_EQ(toString(Failure.takeError()),
 | 
						|
            "Can't parse BenchmarkLog, invalid value 'Unknown'");
 | 
						|
}
 | 
						|
 | 
						|
} // namespace
 | 
						|
} // namespace libc_benchmarks
 | 
						|
} // namespace llvm
 |