blob: 645fa8abf13d7342c07a061df2a67cb4451276a3 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
#include "server/hotspot_partition_calculator.h"
#include "pegasus_server_test_base.h"
#include <gtest/gtest.h>
#include <dsn/utility/fail_point.h>
namespace pegasus {
namespace server {
DSN_DECLARE_int32(occurrence_threshold);
class hotspot_partition_test : public pegasus_server_test_base
{
public:
hotspot_partition_test() : calculator("TEST", 8, nullptr)
{
dsn::fail::setup();
dsn::fail::cfg("send_detect_hotkey_request", "return()");
};
~hotspot_partition_test() { dsn::fail::teardown(); }
hotspot_partition_calculator calculator;
std::vector<row_data> generate_row_data()
{
std::vector<row_data> test_rows;
test_rows.resize(8);
for (int i = 0; i < 8; i++) {
test_rows[i].get_qps = 1000.0;
test_rows[i].put_qps = 1000.0;
}
return test_rows;
}
std::vector<std::array<int, 2>> generate_result()
{
return {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
}
std::vector<std::vector<double>> get_calculator_result(const hot_partition_counters &counters)
{
std::vector<std::vector<double>> result;
result.resize(2);
for (int i = 0; i < counters.size(); i++) {
result[READ_HOTSPOT_DATA].push_back(counters[i][READ_HOTSPOT_DATA].get()->get_value());
result[WRITE_HOTSPOT_DATA].push_back(
counters[i][WRITE_HOTSPOT_DATA].get()->get_value());
}
return result;
}
void test_policy_in_scenarios(std::vector<row_data> scenario,
std::vector<std::vector<double>> &expect_result)
{
calculator.data_aggregate(std::move(scenario));
calculator.data_analyse();
std::vector<std::vector<double>> result = get_calculator_result(calculator._hot_points);
ASSERT_EQ(result, expect_result);
}
void aggregate_analyse_data(std::vector<row_data> scenario,
std::vector<std::array<int, 2>> &expect_result,
int loop_times)
{
for (int i = 0; i < loop_times; i++) {
calculator.data_aggregate(scenario);
calculator.data_analyse();
}
ASSERT_EQ(calculator._hotpartition_counter, expect_result);
}
void clear_calculator_histories() { calculator._partitions_stat_histories.clear(); }
};
TEST_F(hotspot_partition_test, hotspot_partition_policy)
{
// Insert normal scenario data to test
std::vector<row_data> test_rows = generate_row_data();
std::vector<std::vector<double>> expect_vector = {{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}};
test_policy_in_scenarios(test_rows, expect_vector);
// Insert hotspot scenario_0 data to test
test_rows = generate_row_data();
const int HOT_SCENARIO_0_READ_HOT_PARTITION = 7;
const int HOT_SCENARIO_0_WRITE_HOT_PARTITION = 0;
test_rows[HOT_SCENARIO_0_READ_HOT_PARTITION].get_qps = 5000.0;
test_rows[HOT_SCENARIO_0_WRITE_HOT_PARTITION].put_qps = 5000.0;
expect_vector = {{0, 0, 0, 0, 0, 0, 0, 4}, {4, 0, 0, 0, 0, 0, 0, 0}};
test_policy_in_scenarios(test_rows, expect_vector);
// Insert hotspot scenario_0 data to test again
test_rows = generate_row_data();
test_rows[HOT_SCENARIO_0_READ_HOT_PARTITION].get_qps = 5000.0;
test_rows[HOT_SCENARIO_0_WRITE_HOT_PARTITION].put_qps = 5000.0;
expect_vector = {{0, 0, 0, 0, 0, 0, 0, 4}, {4, 0, 0, 0, 0, 0, 0, 0}};
test_policy_in_scenarios(test_rows, expect_vector);
// Insert hotspot scenario_1 data to test again
test_rows = generate_row_data();
const int HOT_SCENARIO_1_READ_HOT_PARTITION = 3;
const int HOT_SCENARIO_1_WRITE_HOT_PARTITION = 2;
test_rows[HOT_SCENARIO_1_READ_HOT_PARTITION].get_qps = 5000.0;
test_rows[HOT_SCENARIO_1_WRITE_HOT_PARTITION].put_qps = 5000.0;
expect_vector = {{0, 0, 0, 4, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 0, 0, 0}};
test_policy_in_scenarios(test_rows, expect_vector);
clear_calculator_histories();
}
TEST_F(hotspot_partition_test, send_detect_hotkey_request)
{
const int READ_HOT_PARTITION = 7;
const int WRITE_HOT_PARTITION = 0;
std::vector<row_data> test_rows = generate_row_data();
test_rows[READ_HOT_PARTITION].get_qps = 5000.0;
test_rows[WRITE_HOT_PARTITION].put_qps = 5000.0;
auto expect_result = generate_result();
expect_result[READ_HOT_PARTITION][0] = FLAGS_occurrence_threshold;
expect_result[WRITE_HOT_PARTITION][1] = FLAGS_occurrence_threshold;
aggregate_analyse_data(test_rows, expect_result, FLAGS_occurrence_threshold);
const int back_to_normal = 30;
expect_result[READ_HOT_PARTITION][0] = FLAGS_occurrence_threshold - back_to_normal;
expect_result[WRITE_HOT_PARTITION][1] = FLAGS_occurrence_threshold - back_to_normal;
aggregate_analyse_data(generate_row_data(), expect_result, back_to_normal);
}
} // namespace server
} // namespace pegasus