From 3f0c570007b4487eb50ba16268775bd39317a057 Mon Sep 17 00:00:00 2001 From: George Arama <50641385+gearama@users.noreply.github.com> Date: Tue, 21 Jun 2022 15:46:08 -0700 Subject: [PATCH] Perf test for certs (#3729) * one commit to rule them all * main merge * error * main merge * error * main merge * error * main merge * error * example of perf test * remove file * create certs and keys in post setup, use to run the test * PR comments --- CMakeSettings.json | 23 ++- .../CMakeLists.txt | 6 +- .../test/perf/CMakeLists.txt | 38 +++++ .../test/get_certificate_test.hpp | 154 ++++++++++++++++++ ...curity_keyvault_certificates_perf_test.cpp | 18 ++ .../azure/keyvault/keys/test/get_key_test.hpp | 48 ++++-- 6 files changed, 273 insertions(+), 14 deletions(-) create mode 100644 sdk/keyvault/azure-security-keyvault-certificates/test/perf/CMakeLists.txt create mode 100644 sdk/keyvault/azure-security-keyvault-certificates/test/perf/inc/azure/keyvault/certificates/test/get_certificate_test.hpp create mode 100644 sdk/keyvault/azure-security-keyvault-certificates/test/perf/src/azure_security_keyvault_certificates_perf_test.cpp diff --git a/CMakeSettings.json b/CMakeSettings.json index 445a2b695..c10c6410f 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -21,7 +21,6 @@ "value": "True", "type": "BOOL" } - ] }, { @@ -231,6 +230,28 @@ "type": "BOOL" } ] + }, + { + "name": "x64-DebugWithPerfTest", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "-DINSTALL_GTEST=OFF -DBUILD_TESTING=ON -DBUILD_TRANSPORT_CURL=ON -DBUILD_SAMPLES=ON -DBUILD_PERFORMANCE_TESTS=ON", + "buildCommandArgs": "-v", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [ + { + "name": "VCPKG_TARGET_TRIPLET", + "value": "x64-windows-static", + "type": "STRING" + }, + { + "name": "MSVC_USE_STATIC_CRT", + "value": "True", + "type": "BOOL" + } + ] } ] } \ No newline at end of file diff --git a/sdk/keyvault/azure-security-keyvault-certificates/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-certificates/CMakeLists.txt index 205a5e008..40c099e2a 100644 --- a/sdk/keyvault/azure-security-keyvault-certificates/CMakeLists.txt +++ b/sdk/keyvault/azure-security-keyvault-certificates/CMakeLists.txt @@ -112,9 +112,9 @@ if(BUILD_TESTING) endif() -# if (BUILD_PERFORMANCE_TESTS) -# add_subdirectory(test/perf) -# endif() +if (BUILD_PERFORMANCE_TESTS) + add_subdirectory(test/perf) +endif() if(BUILD_SAMPLES) add_subdirectory(test/samples) diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/perf/CMakeLists.txt b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/CMakeLists.txt new file mode 100644 index 000000000..5ef328b4f --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +# Configure CMake project. +cmake_minimum_required (VERSION 3.13) +project(azure-security-keyvault-certificates-perf LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set( + AZURE_KEYVAULT_CERTIFICATES_PERF_TEST_HEADER + inc/azure/keyvault/certificates/test/get_certificate_test.hpp +) + +set( + AZURE_KEYVAULT_CERTIFICATES_PERF_TEST_SOURCE + src/azure_security_keyvault_certificates_perf_test.cpp +) + +# Name the binary to be created. +add_executable ( + azure-security-keyvault-certificates-perf + ${AZURE_KEYVAULT_CERTIFICATES_PERF_TEST_HEADER} ${AZURE_KEYVAULT_CERTIFICATES_PERF_TEST_SOURCE} +) +create_per_service_target_build(keyvault azure-security-keyvault-certificates-perf) +create_map_file(azure-security-keyvault-certificates-perf azure-security-keyvault-certificates-perf.map) + +# Include the headers from the project. +target_include_directories( + azure-security-keyvault-certificates-perf + PUBLIC + $ +) + +# link the `azure-perf` lib together with any other library which will be used for the tests. +target_link_libraries(azure-security-keyvault-certificates-perf PRIVATE azure-identity azure-security-keyvault-certificates azure-perf) +# Make sure the project will appear in the test folder for Visual Studio CMake view +set_target_properties(azure-security-keyvault-certificates-perf PROPERTIES FOLDER "Tests/Keyvault") diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/perf/inc/azure/keyvault/certificates/test/get_certificate_test.hpp b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/inc/azure/keyvault/certificates/test/get_certificate_test.hpp new file mode 100644 index 000000000..4cfb141dd --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/inc/azure/keyvault/certificates/test/get_certificate_test.hpp @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +/** + * @file + * @brief Test the overhead of getting a certificate. + * + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace Azure::Core::_internal; + +namespace Azure { + namespace Security { + namespace KeyVault { + namespace Certificates { + namespace Test { + + /** + * @brief A test to measure getting a key performance. + * + */ + class GetCertificate : public Azure::Perf::PerfTest { + private: + std::string m_vaultUrl; + std::string m_certificateName; + std::string m_tenantId; + std::string m_clientId; + std::string m_secret; + std::shared_ptr m_credential; + std::unique_ptr m_client; + + public: + /** + * @brief Get the Ids and secret + * + */ + void Setup() override + { + m_vaultUrl = m_options.GetOptionOrDefault( + "vaultUrl", Environment::GetVariable("AZURE_KEYVAULT_URL")); + m_tenantId = m_options.GetOptionOrDefault( + "TenantId", Environment::GetVariable("AZURE_TENANT_ID")); + m_clientId = m_options.GetOptionOrDefault( + "ClientId", Environment::GetVariable("AZURE_CLIENT_ID")); + m_secret = m_options.GetOptionOrDefault( + "Secret", Environment::GetVariable("AZURE_CLIENT_SECRET")); + m_credential = std::make_shared( + m_tenantId, m_clientId, m_secret); + m_client = std::make_unique( + m_vaultUrl, + m_credential, + InitClientOptions()); + this->CreateRandomNameCertificate(); + } + + /** + * @brief Create a random named certificate. + * + */ + void CreateRandomNameCertificate() + { + std::string name("perf"); + int suffixLen = 10; + static const char alphanum[] + = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + std::string suffix; + suffix.reserve(suffixLen); + + for (int i = 0; i < suffixLen; ++i) + { + suffix += alphanum[rand() % (sizeof(alphanum) - 1)]; + } + + m_certificateName = name + suffix; + CertificateCreateOptions options; + options.Policy.Subject = "CN=xyz"; + options.Policy.ValidityInMonths = 12; + options.Policy.Enabled = true; + + options.Properties.Enabled = true; + options.Properties.Name = m_certificateName; + options.Policy.ContentType = CertificateContentType::Pkcs12; + options.Policy.IssuerName = "Self"; + + LifetimeAction action; + action.LifetimePercentage = 80; + action.Action = CertificatePolicyAction::AutoRenew; + options.Policy.LifetimeActions.emplace_back(action); + auto duration = std::chrono::minutes(5); + auto deadline = std::chrono::system_clock::now() + duration; + Azure::Core::Context context; + auto response = m_client->StartCreateCertificate( + m_certificateName, options, context.WithDeadline(deadline)); + auto pollResult = response.PollUntilDone(std::chrono::milliseconds(2000)); + } + + /** + * @brief Construct a new GetCertificate test. + * + * @param options The test options. + */ + GetCertificate(Azure::Perf::TestOptions options) : PerfTest(options) {} + + /** + * @brief Define the test + * + */ + void Run(Azure::Core::Context const&) override + { + auto t = m_client->GetCertificate(m_certificateName); + } + + /** + * @brief Define the test options for the test. + * + * @return The list of test options. + */ + std::vector GetTestOptions() override + { + return { + {"vaultUrl", {"--vaultUrl"}, "The Key Vault Account.", 1, false}, + {"TenantId", {"--tenantId"}, "The tenant Id for the authentication.", 1, false}, + {"ClientId", {"--clientId"}, "The client Id for the authentication.", 1, false}, + {"Secret", {"--secret"}, "The secret for authentication.", 1, false, true}}; + } + + /** + * @brief Get the static Test Metadata for the test. + * + * @return Azure::Perf::TestMetadata describing the test. + */ + static Azure::Perf::TestMetadata GetTestMetadata() + { + return { + "GetCertificate", "Get a certificate", [](Azure::Perf::TestOptions options) { + return std::make_unique( + options); + }}; + } + }; + +}}}}} // namespace Azure::Security::KeyVault::Certificates::Test diff --git a/sdk/keyvault/azure-security-keyvault-certificates/test/perf/src/azure_security_keyvault_certificates_perf_test.cpp b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/src/azure_security_keyvault_certificates_perf_test.cpp new file mode 100644 index 000000000..e0c2e4486 --- /dev/null +++ b/sdk/keyvault/azure-security-keyvault-certificates/test/perf/src/azure_security_keyvault_certificates_perf_test.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include "azure/keyvault/certificates/test/get_certificate_test.hpp" + +int main(int argc, char** argv) +{ + + // Create the test list + std::vector tests{ + Azure::Security::KeyVault::Certificates::Test::GetCertificate::GetTestMetadata()}; + + Azure::Perf::Program::Run(Azure::Core::Context::ApplicationContext, tests, argc, argv); + + return 0; +} diff --git a/sdk/keyvault/azure-security-keyvault-keys/test/perf/inc/azure/keyvault/keys/test/get_key_test.hpp b/sdk/keyvault/azure-security-keyvault-keys/test/perf/inc/azure/keyvault/keys/test/get_key_test.hpp index c75f7a0ef..339afc529 100644 --- a/sdk/keyvault/azure-security-keyvault-keys/test/perf/inc/azure/keyvault/keys/test/get_key_test.hpp +++ b/sdk/keyvault/azure-security-keyvault-keys/test/perf/inc/azure/keyvault/keys/test/get_key_test.hpp @@ -11,6 +11,7 @@ #include +#include #include #include @@ -18,6 +19,7 @@ #include #include +using namespace Azure::Core::_internal; namespace Azure { namespace Security { namespace KeyVault { namespace Keys { namespace Test { /** @@ -41,17 +43,44 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys { nam */ void Setup() override { - m_vaultUrl = m_options.GetMandatoryOption("vaultUrl"); - m_keyName = m_options.GetMandatoryOption("keyName"); - m_tenantId = m_options.GetMandatoryOption("TenantId"); - m_clientId = m_options.GetMandatoryOption("ClientId"); - m_secret = m_options.GetMandatoryOption("Secret"); + m_vaultUrl = m_options.GetOptionOrDefault( + "vaultUrl", Environment::GetVariable("AZURE_KEYVAULT_URL")); + m_tenantId = m_options.GetOptionOrDefault( + "TenantId", Environment::GetVariable("AZURE_TENANT_ID")); + m_clientId = m_options.GetOptionOrDefault( + "ClientId", Environment::GetVariable("AZURE_CLIENT_ID")); + m_secret = m_options.GetOptionOrDefault( + "Secret", Environment::GetVariable("AZURE_CLIENT_SECRET")); m_credential = std::make_shared( m_tenantId, m_clientId, m_secret); m_client = std::make_unique( m_vaultUrl, m_credential, InitClientOptions()); + this->CreateRandomNameKey(); + } + + /** + * @brief Create a random named certificate. + * + */ + void CreateRandomNameKey() + { + std::string name("perf"); + int suffixLen = 10; + static const char alphanum[] + = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + std::string suffix; + suffix.reserve(suffixLen); + + for (int i = 0; i < suffixLen; ++i) + { + suffix += alphanum[rand() % (sizeof(alphanum) - 1)]; + } + + m_keyName = name + suffix; + auto ecKey = Azure::Security::KeyVault::Keys::CreateEcKeyOptions(m_keyName); + auto keyResponse = m_client->CreateEcKey(ecKey); } /** @@ -75,11 +104,10 @@ namespace Azure { namespace Security { namespace KeyVault { namespace Keys { nam std::vector GetTestOptions() override { return { - {"vaultUrl", {"--vaultUrl"}, "The Key Vault Account.", 1, true}, - {"keyName", {"--keyName"}, "The Key name to get.", 1, true}, - {"TenantId", {"--tenantId"}, "The tenant Id for the authentication.", 1, true}, - {"ClientId", {"--clientId"}, "The client Id for the authentication.", 1, true}, - {"Secret", {"--secret"}, "The secret for authentication.", 1, true, true}}; + {"vaultUrl", {"--vaultUrl"}, "The Key Vault Account.", 1, false}, + {"TenantId", {"--tenantId"}, "The tenant Id for the authentication.", 1, false}, + {"ClientId", {"--clientId"}, "The client Id for the authentication.", 1, false}, + {"Secret", {"--secret"}, "The secret for authentication.", 1, false, true}}; } /**