From dcb87304c3e74559386d39a303da5bde34fb8754 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 18 Aug 2014 11:40:46 +0200 Subject: [PATCH] Add performance tests for PolicyBucket Change-Id: I3b7f88a7964552664f0a1d1b1a56916ac0726249 --- test/Benchmark.h | 50 +++++++++++++++++ test/CMakeLists.txt | 1 + test/storage/performance/bucket.cpp | 106 ++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 test/Benchmark.h create mode 100644 test/storage/performance/bucket.cpp diff --git a/test/Benchmark.h b/test/Benchmark.h new file mode 100644 index 0000000..9902236 --- /dev/null +++ b/test/Benchmark.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file Benchmark.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief A generic benchmark + */ + +#ifndef TEST_BENCHMARK_H_ +#define TEST_BENCHMARK_H_ + +#include + +namespace Cynara { + +namespace Benchmark { + +typedef std::function Function; + +template +Precision measure(Function fn) { + using std::chrono::high_resolution_clock; + + high_resolution_clock::time_point t0 = high_resolution_clock::now(); + fn(); + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + + return std::chrono::duration_cast(t1 - t0); +} + +} // namespace Benchmark + +} // namespace Cynara + + +#endif /* TEST_BENCHMARK_H_ */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0f64ab4..c3e3eea 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -36,6 +36,7 @@ SET(CYNARA_SOURCES_FOR_TESTS SET(CYNARA_TESTS_SOURCES common/exceptions/bucketrecordcorrupted.cpp types/policykey.cpp + storage/performance/bucket.cpp storage/storage/policies.cpp storage/storage/check.cpp storage/storage/buckets.cpp diff --git a/test/storage/performance/bucket.cpp b/test/storage/performance/bucket.cpp new file mode 100644 index 0000000..264482f --- /dev/null +++ b/test/storage/performance/bucket.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file bucket.cpp + * @author Aleksander Zdyb + * @version 1.0 + * @brief Performance tests for Cynara::PolicyBucket + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "../../Benchmark.h" + +using namespace Cynara; + +class Benchmark { +public: + +}; + +class PolicyKeyGenerator { +public: + typedef std::vector Features; + typedef std::reference_wrapper FeaturesRef; + + PolicyKeyGenerator(size_t featuresCount, size_t featureLength) { + const std::vector toGenerate = { m_clients, m_users, m_privileges }; + for (auto featuresRef : toGenerate) { + auto &features = featuresRef.get(); + features.resize(featuresCount); + std::generate(std::begin(features), std::end(features), + std::bind(&PolicyKeyGenerator::randomKeyFeature, this, featureLength)); + } + } + + PolicyKey randomKey(void) const { + return { m_clients.at(rand() % m_clients.size()), + m_users.at(rand() % m_users.size()), + m_privileges.at(rand() % m_privileges.size()) + }; + } + + char randomChar(void) const { + return (std::rand() % ('z' - 'a')) + 'a'; + } + + std::string randomKeyFeature(size_t length) const { + std::string str(length, 0); + std::generate_n( str.begin(), length, std::bind(&PolicyKeyGenerator::randomChar, this)); + return str; + } + +private: + Features m_clients; + Features m_users; + Features m_privileges; +}; + +TEST(Performance, bucket_filtered_100000) { + using std::chrono::microseconds; + + PolicyBucket bucket; + + PolicyKeyGenerator generator(100, 10); + + const std::size_t policyNumber = 100000; + for (std::size_t i = 0; i < policyNumber; ++i) { + bucket.insertPolicy(std::make_shared(generator.randomKey(), + PredefinedPolicyType::ALLOW)); + } + + const unsigned int measureRepeats = 1000; + auto result = Benchmark::measure([&bucket, &generator, measureRepeats] () { + for (auto i = 0u; i < measureRepeats; ++i) { + bucket.filtered(generator.randomKey()); + } + }); + + auto key = std::string("performance_" + std::to_string(policyNumber)); + auto value = std::to_string(result.count() / measureRepeats) + " [us]"; + RecordProperty(key, value); +} -- 2.7.4