From 50cc74286566e6810a3a51ac26b5cf3b54647da9 Mon Sep 17 00:00:00 2001 From: George Arama <50641385+gearama@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:20:52 -0800 Subject: [PATCH] Json test (#5324) * mroe quotes * dssf * sqa * Json test p1 * qw * re * pr build * cast part 2 * ew * jj --- sdk/core/azure-core/test/perf/CMakeLists.txt | 1 + .../perf/inc/azure/core/test/json_test.hpp | 321 ++++++++++++++++++ .../test/perf/src/azure_core_perf_test.cpp | 2 + 3 files changed, 324 insertions(+) create mode 100644 sdk/core/azure-core/test/perf/inc/azure/core/test/json_test.hpp diff --git a/sdk/core/azure-core/test/perf/CMakeLists.txt b/sdk/core/azure-core/test/perf/CMakeLists.txt index 5b5470104..b9a474c7a 100644 --- a/sdk/core/azure-core/test/perf/CMakeLists.txt +++ b/sdk/core/azure-core/test/perf/CMakeLists.txt @@ -10,6 +10,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) set( AZURE_CORE_PERF_TEST_HEADER inc/azure/core/test/http_transport_test.hpp + inc/azure/core/test/json_test.hpp inc/azure/core/test/nullable_test.hpp inc/azure/core/test/pipeline_test.hpp inc/azure/core/test/uuid_test.hpp diff --git a/sdk/core/azure-core/test/perf/inc/azure/core/test/json_test.hpp b/sdk/core/azure-core/test/perf/inc/azure/core/test/json_test.hpp new file mode 100644 index 000000000..cb1b689ed --- /dev/null +++ b/sdk/core/azure-core/test/perf/inc/azure/core/test/json_test.hpp @@ -0,0 +1,321 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * @file + * @brief Test the JSON performance. + * + */ + +#pragma once + +#include "../../../core/perf/inc/azure/perf.hpp" + +#include +#include +#include + +#include + +using namespace Azure::Core::Json::_internal; + +#include + +namespace Azure { namespace Core { namespace Test { + + struct JsonTestObject + { + // stack + bool Boolean; + int8_t Int8; + int16_t Int16; + int32_t Int32; + int64_t Int64; + uint8_t Uint8; + uint16_t Uint16; + uint32_t Uint32; + uint64_t Uint64; + float Float; + double Double; + std::string String; + + // nullables + Azure::Nullable NullableBoolean; + Azure::Nullable NullableInt8; + Azure::Nullable NullableInt16; + Azure::Nullable NullableInt32; + Azure::Nullable NullableInt64; + Azure::Nullable NullableUint8; + Azure::Nullable NullableUint16; + Azure::Nullable NullableUint32; + Azure::Nullable NullableUint64; + Azure::Nullable NullableFloat; + Azure::Nullable NullableDouble; + Azure::Nullable NullableString; + + // vectors + std::vector Booleans; + std::vector Int8s; + std::vector Int16s; + std::vector Int32s; + std::vector Int64s; + std::vector Uint8s; + std::vector Uint16s; + std::vector Uint32s; + std::vector Uint64s; + std::vector Floats; + std::vector Doubles; + std::vector Strings; + + // Map + std::map Map; + + bool operator==(const JsonTestObject& other) const + { + return Boolean == other.Boolean && Int8 == other.Int8 && Int16 == other.Int16 + && Int32 == other.Int32 && Int64 == other.Int64 && Uint8 == other.Uint8 + && Uint16 == other.Uint16 && Uint32 == other.Uint32 && Uint64 == other.Uint64 + && Float == other.Float && Double == other.Double && String == other.String + && Booleans == other.Booleans && Int8s == other.Int8s && Int16s == other.Int16s + && Int32s == other.Int32s && Int64s == other.Int64s && Uint8s == other.Uint8s + && Uint16s == other.Uint16s && Uint32s == other.Uint32s && Uint64s == other.Uint64s + && Floats == other.Floats && Doubles == other.Doubles && Strings == other.Strings + && Map == other.Map; + } + + std::string Serialize() const + { + Azure::Core::Json::_internal::json j; + + j["Boolean"] = Boolean; + j["Int8"] = Int8; + j["Int16"] = Int16; + j["Int32"] = Int32; + j["Int64"] = Int64; + j["Uint8"] = Uint8; + j["Uint16"] = Uint16; + j["Uint32"] = Uint32; + j["Uint64"] = Uint64; + j["Float"] = Float; + j["Double"] = Double; + j["String"] = String; + + JsonOptional::SetFromNullable(NullableBoolean, j, "NullableBoolean"); + JsonOptional::SetFromNullable(NullableInt8, j, "NullableInt8"); + JsonOptional::SetFromNullable(NullableInt16, j, "NullableInt16"); + JsonOptional::SetFromNullable(NullableInt32, j, "NullableInt32"); + JsonOptional::SetFromNullable(NullableInt64, j, "NullableInt64"); + JsonOptional::SetFromNullable(NullableUint8, j, "NullableUint8"); + JsonOptional::SetFromNullable(NullableUint16, j, "NullableUint16"); + JsonOptional::SetFromNullable(NullableUint32, j, "NullableUint32"); + JsonOptional::SetFromNullable(NullableUint64, j, "NullableUint64"); + JsonOptional::SetFromNullable(NullableFloat, j, "NullableFloat"); + JsonOptional::SetFromNullable(NullableDouble, j, "NullableDouble"); + JsonOptional::SetFromNullable(NullableString, j, "NullableString"); + + j["Booleans"] = Booleans; + j["Int8s"] = Int8s; + j["Int16s"] = Int16s; + j["Int32s"] = Int32s; + j["Int64s"] = Int64s; + j["Uint8s"] = Uint8s; + j["Uint16s"] = Uint16s; + j["Uint32s"] = Uint32s; + j["Uint64s"] = Uint64s; + j["Floats"] = Floats; + j["Doubles"] = Doubles; + j["Strings"] = Strings; + + for (auto const& pair : Map) + { + j["Map"][pair.first] = pair.second; + }; + + return j.dump(); + } + + void Deserialize(std::string const& json) + { + Azure::Core::Json::_internal::json j = Azure::Core::Json::_internal::json::parse(json); + + Boolean = j["Boolean"].get(); + Int8 = j["Int8"].get(); + Int16 = j["Int16"].get(); + Int32 = j["Int32"].get(); + Int64 = j["Int64"].get(); + Uint8 = j["Uint8"].get(); + Uint16 = j["Uint16"].get(); + Uint32 = j["Uint32"].get(); + Uint64 = j["Uint64"].get(); + Float = j["Float"].get(); + Double = j["Double"].get(); + String = j["String"].get(); + + JsonOptional::SetIfExists(NullableBoolean, j, "NullableBoolean"); + JsonOptional::SetIfExists(NullableInt8, j, "NullableInt8"); + JsonOptional::SetIfExists(NullableInt16, j, "NullableInt16"); + JsonOptional::SetIfExists(NullableInt32, j, "NullableInt32"); + JsonOptional::SetIfExists(NullableInt64, j, "NullableInt64"); + JsonOptional::SetIfExists(NullableUint8, j, "NullableUint8"); + JsonOptional::SetIfExists(NullableUint16, j, "NullableUint16"); + JsonOptional::SetIfExists(NullableUint32, j, "NullableUint32"); + JsonOptional::SetIfExists(NullableUint64, j, "NullableUint64"); + JsonOptional::SetIfExists(NullableFloat, j, "NullableFloat"); + JsonOptional::SetIfExists(NullableDouble, j, "NullableDouble"); + JsonOptional::SetIfExists(NullableString, j, "NullableString"); + + Booleans = j["Booleans"].get>(); + Int8s = j["Int8s"].get>(); + Int16s = j["Int16s"].get>(); + Int32s = j["Int32s"].get>(); + Int64s = j["Int64s"].get>(); + Uint8s = j["Uint8s"].get>(); + Uint16s = j["Uint16s"].get>(); + Uint32s = j["Uint32s"].get>(); + Uint64s = j["Uint64s"].get>(); + Floats = j["Floats"].get>(); + Doubles = j["Doubles"].get>(); + Strings = j["Strings"].get>(); + + for (auto const& pair : j["Map"].items()) + { + Map[pair.key()] = pair.value().get(); + } + } + + JsonTestObject() = default; + JsonTestObject(size_t const& vectorSize) + { + Boolean = true; + Int8 = static_cast(1); + Int16 = static_cast(2); + Int32 = static_cast(3); + Int64 = static_cast(4); + Uint8 = static_cast(5); + Uint16 = static_cast(6); + Uint32 = static_cast(7); + Uint64 = static_cast(8); + Float = static_cast(9.0); + Double = static_cast(10.0); + String = "string"; + + NullableBoolean = true; + NullableInt8 = static_cast(1); + NullableInt16 = static_cast(2); + NullableInt32 = static_cast(3); + NullableInt64 = static_cast(4); + NullableUint8 = static_cast(5); + NullableUint16 = static_cast(6); + NullableUint32 = static_cast(7); + NullableUint64 = static_cast(8); + NullableFloat = static_cast(9.0); + NullableDouble = static_cast(10.0); + NullableString = "string"; + + Booleans = std::vector(vectorSize, true); + Int8s = std::vector(vectorSize, static_cast(1)); + Int16s = std::vector(vectorSize, static_cast(2)); + Int32s = std::vector(vectorSize, static_cast(3)); + Int64s = std::vector(vectorSize, static_cast(4)); + Uint8s = std::vector(vectorSize, static_cast(5)); + Uint16s = std::vector(vectorSize, static_cast(6)); + Uint32s = std::vector(vectorSize, static_cast(7)); + Uint64s = std::vector(vectorSize, static_cast(8)); + Floats = std::vector(vectorSize, static_cast(9.0)); + Doubles = std::vector(vectorSize, static_cast(10.0)); + Strings = std::vector(vectorSize, "string"); + + Map = std::map(); + for (size_t i = 0; i < vectorSize; i++) + { + Map["key" + std::to_string(i)] = "value" + std::to_string(i); + }; + } + }; + + /** + * @brief Measure the HTTP transport performance. + */ + class JsonTest : public Azure::Perf::PerfTest { + enum class Action + { + Serialize, + Deserialize + }; + + Action m_action; + size_t m_vectorSize; + JsonTestObject m_testObject; + std::string m_jsonBody; + + public: + /** + * @brief Construct a new JsonTest test. + * + * @param options The test options. + */ + JsonTest(Azure::Perf::TestOptions options) : PerfTest(options) {} + + void Setup() override + { + m_action = m_options.GetOptionOrDefault("Action", "serialize") == "serialize" + ? Action::Serialize + : Action::Deserialize; + + m_vectorSize = m_options.GetOptionOrDefault("Size", 1000); + m_testObject = JsonTestObject(m_vectorSize); + + if (m_action == Action::Deserialize) + { + m_jsonBody = m_testObject.Serialize(); + } + } + + /** + * @brief Perform Json test. + * + */ + void Run(Azure::Core::Context const&) override + { + switch (m_action) + { + case Action::Serialize: { + m_testObject.Serialize(); + break; + } + case Action::Deserialize: { + m_testObject.Deserialize(m_jsonBody); + break; + } + } + } + + /** + * @brief Define the test options for the test. + * + * @return The list of test options. + */ + std::vector GetTestOptions() override + { + return { + {"Action", {"--action"}, "Serialize/deserialize, default serialize", 1, false}, + {"Size", {"--size"}, "The vector size, default 1000", 1, false}}; + } + + /** + * @brief Get the static Test Metadata for the test. + * + * @return Azure::Perf::TestMetadata describing the test. + */ + static Azure::Perf::TestMetadata GetTestMetadata() + { + return { + "JsonTest", + "Measures Json serialize/deserialize performance", + [](Azure::Perf::TestOptions options) { + return std::make_unique(options); + }}; + } + }; + +}}} // namespace Azure::Core::Test diff --git a/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp b/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp index 224f97d54..509a95f09 100644 --- a/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp +++ b/sdk/core/azure-core/test/perf/src/azure_core_perf_test.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "azure/core/test/http_transport_test.hpp" +#include "azure/core/test/json_test.hpp" #include "azure/core/test/nullable_test.hpp" #include "azure/core/test/pipeline_test.hpp" #include "azure/core/test/uuid_test.hpp" @@ -16,6 +17,7 @@ int main(int argc, char** argv) // Create the test list std::vector tests{ Azure::Core::Test::HTTPTransportTest::GetTestMetadata(), + Azure::Core::Test::JsonTest::GetTestMetadata(), Azure::Core::Test::NullableTest::GetTestMetadata(), Azure::Core::Test::PipelineTest::GetTestMetadata(), Azure::Core::Test::UuidTest::GetTestMetadata()};