blob: 8de287862fde0c13e7adc8247b346ec1ba33eff5 [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 <fmt/core.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include "gtest/gtest.h"
#include "http/builtin_http_calls.h"
#include "http/http_call_registry.h"
#include "http/http_server.h"
#include "http/http_status_code.h"
#include "replica/replica_http_service.h"
#include "replica/test/mock_utils.h"
#include "replica/test/replica_test_base.h"
#include "utils/flags.h"
#include "utils/test_macros.h"
using std::map;
using std::string;
namespace dsn {
namespace security {
DSN_DECLARE_bool(enable_acl);
} // namespace security
namespace replication {
DSN_DECLARE_bool(duplication_enabled);
DSN_DECLARE_bool(fd_disabled);
DSN_DECLARE_uint32(config_sync_interval_ms);
class replica_http_service_test : public replica_test_base
{
public:
replica_http_service_test()
{
// Disable unnecessary works before starting stub.
FLAGS_fd_disabled = true;
FLAGS_duplication_enabled = false;
// Set FLAGS_enable_acl to true, ensuring the group validator's
// encrypt_data_at_rest_pre_check
// is successful when encrypt_data_at_rest is also true.
// TODO(jingwei): It's a trick for test, it should set together at class
// pegasus::encrypt_data_at_rest.
dsn::security::FLAGS_enable_acl = true;
stub->initialize_start();
http_call_registry::instance().clear_paths();
_http_svc = std::make_unique<replica_http_service>(stub.get());
}
void SetUp() override
{
// Reset config_sync_interval_ms to 30000.
NO_FATALS(test_update_config({{"config_sync_interval_ms", "30000"}},
R"({"update_status":"ERR_OK"})"
"\n"));
NO_FATALS(test_check_config("config_sync_interval_ms", "30000"));
}
void test_update_config(const map<string, string> &configs, const string &expect_resp)
{
http_request req;
for (const auto &config : configs) {
req.query_args[config.first] = config.second;
}
http_response resp;
_http_svc->update_config_handler(req, resp);
ASSERT_EQ(resp.status_code, http_status_code::kOk);
ASSERT_EQ(expect_resp, resp.body);
}
void test_check_config(const string &config, const string &expect_value)
{
http_request req;
http_response resp;
req.query_args["name"] = config;
get_config(req, resp);
ASSERT_EQ(resp.status_code, http_status_code::kOk);
const string unfilled_resp =
R"({{"name":"config_sync_interval_ms","section":"replication","type":"FV_UINT32","tags":"flag_tag::FT_MUTABLE","description":"The interval milliseconds of replica server to syncs replica configuration with meta server","value":"{}"}})"
"\n";
ASSERT_EQ(fmt::format(unfilled_resp, expect_value), resp.body);
}
private:
std::unique_ptr<replica_http_service> _http_svc;
};
INSTANTIATE_TEST_SUITE_P(, replica_http_service_test, ::testing::Values(false, true));
TEST_P(replica_http_service_test, update_config_handler)
{
// Test the default value.
NO_FATALS(test_check_config("config_sync_interval_ms", "30000"));
ASSERT_EQ(30000, FLAGS_config_sync_interval_ms);
// Update config failed and value not changed.
NO_FATALS(test_update_config(
{},
R"({"update_status":"ERR_INVALID_PARAMETERS: there should be exactly one config to be updated once"})"
"\n"));
NO_FATALS(test_check_config("config_sync_interval_ms", "30000"));
ASSERT_EQ(30000, FLAGS_config_sync_interval_ms);
// Update config failed and value not changed.
NO_FATALS(test_update_config(
{{"config_sync_interval_ms", "10"}, {"hdfs_write_limit_rate_mb_per_sec", "50"}},
R"({"update_status":"ERR_INVALID_PARAMETERS: there should be exactly one config to be updated once"})"
"\n"));
NO_FATALS(test_check_config("config_sync_interval_ms", "30000"));
ASSERT_EQ(30000, FLAGS_config_sync_interval_ms);
// Update config failed and value not changed.
NO_FATALS(test_update_config({{"config_sync_interval_ms", "-1"}},
R"({"update_status":"ERR_INVALID_PARAMETERS: -1 is invalid"})"
"\n"));
NO_FATALS(test_check_config("config_sync_interval_ms", "30000"));
ASSERT_EQ(30000, FLAGS_config_sync_interval_ms);
// Update config success and value changed.
NO_FATALS(test_update_config({{"config_sync_interval_ms", "10"}},
R"({"update_status":"ERR_OK"})"
"\n"));
NO_FATALS(test_check_config("config_sync_interval_ms", "10"));
ASSERT_EQ(10, FLAGS_config_sync_interval_ms);
}
} // namespace replication
} // namespace dsn