blob: 69b32c94d4bb09b80a81bef1a365b799851cfeb2 [file]
/** @file
Unit tests for plugin.config parser and marshaller.
@section license License
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 <catch2/catch_test_macros.hpp>
#include <filesystem>
#include <fstream>
#include <yaml-cpp/yaml.h>
#include "config/plugin_config.h"
namespace
{
class TempFile
{
public:
TempFile(std::string const &filename, std::string const &content)
{
_path = std::filesystem::temp_directory_path() / filename;
std::ofstream ofs(_path);
ofs << content;
}
~TempFile() { std::filesystem::remove(_path); }
std::string
path() const
{
return _path.string();
}
private:
std::filesystem::path _path;
};
} // namespace
TEST_CASE("plugin_config parser - basic active plugins", "[plugin_config]")
{
TempFile tf("plugin_basic.config", "stats_over_http.so _stats\nheader_rewrite.so /etc/trafficserver/rewrite.conf\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 2);
CHECK(result.value[0].path == "stats_over_http.so");
CHECK(result.value[0].enabled == true);
REQUIRE(result.value[0].args.size() == 1);
CHECK(result.value[0].args[0] == "_stats");
CHECK(result.value[1].path == "header_rewrite.so");
CHECK(result.value[1].enabled == true);
REQUIRE(result.value[1].args.size() == 1);
CHECK(result.value[1].args[0] == "/etc/trafficserver/rewrite.conf");
}
TEST_CASE("plugin_config parser - commented lines become disabled", "[plugin_config]")
{
TempFile tf("plugin_commented.config", "stats_over_http.so\n# cache_promote.so --policy=lru\nxdebug.so\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 3);
CHECK(result.value[0].path == "stats_over_http.so");
CHECK(result.value[0].enabled == true);
CHECK(result.value[1].path == "cache_promote.so");
CHECK(result.value[1].enabled == false);
REQUIRE(result.value[1].args.size() == 1);
CHECK(result.value[1].args[0] == "--policy=lru");
CHECK(result.value[2].path == "xdebug.so");
CHECK(result.value[2].enabled == true);
}
TEST_CASE("plugin_config parser - pure comment lines are skipped", "[plugin_config]")
{
TempFile tf("plugin_pure_comments.config", "# This is just a comment\n# Another comment line\nstats_over_http.so\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 1);
CHECK(result.value[0].path == "stats_over_http.so");
}
TEST_CASE("plugin_config parser - blank lines", "[plugin_config]")
{
TempFile tf("plugin_blanks.config", "\n\nstats_over_http.so\n\nxdebug.so\n\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 2);
}
TEST_CASE("plugin_config parser - quoted arguments", "[plugin_config]")
{
TempFile tf("plugin_quoted.config", "my_plugin.so \"arg with spaces\" second_arg\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 1);
REQUIRE(result.value[0].args.size() == 2);
CHECK(result.value[0].args[0] == "arg with spaces");
CHECK(result.value[0].args[1] == "second_arg");
}
TEST_CASE("plugin_config parser - plugin with no args", "[plugin_config]")
{
TempFile tf("plugin_noargs.config", "xdebug.so\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 1);
CHECK(result.value[0].path == "xdebug.so");
CHECK(result.value[0].args.empty());
}
TEST_CASE("plugin_config parser - dollar record references preserved", "[plugin_config]")
{
TempFile tf("plugin_dollar.config", "my_plugin.so $proxy.config.http.server_ports\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
REQUIRE(result.value.size() == 1);
REQUIRE(result.value[0].args.size() == 1);
CHECK(result.value[0].args[0] == "$proxy.config.http.server_ports");
}
TEST_CASE("plugin_config parser - nonexistent file", "[plugin_config]")
{
auto result = config::PluginConfigParser{}.parse("/nonexistent/path/plugin.config");
CHECK(!result.ok());
CHECK(result.file_not_found == true);
}
TEST_CASE("plugin_config marshaller - basic output", "[plugin_config]")
{
config::PluginConfigData data = {
{"stats_over_http.so", {"_stats"}, true },
{"cache_promote.so", {"--policy=lru", "--buckets=100"}, false},
{"xdebug.so", {}, true },
};
auto yaml = config::PluginConfigMarshaller{}.to_yaml(data);
YAML::Node root = YAML::Load(yaml);
REQUIRE(root["plugins"]);
REQUIRE(root["plugins"].IsSequence());
REQUIRE(root["plugins"].size() == 3);
CHECK(root["plugins"][0]["path"].as<std::string>() == "stats_over_http.so");
CHECK_FALSE(root["plugins"][0]["enabled"]);
CHECK(root["plugins"][1]["path"].as<std::string>() == "cache_promote.so");
CHECK(root["plugins"][1]["enabled"].as<bool>() == false);
CHECK(root["plugins"][1]["params"].size() == 2);
CHECK(root["plugins"][2]["path"].as<std::string>() == "xdebug.so");
CHECK_FALSE(root["plugins"][2]["params"]);
}
TEST_CASE("plugin_config round-trip parse then marshal", "[plugin_config]")
{
TempFile tf("plugin_roundtrip.config",
"stats_over_http.so _stats\n# cache_promote.so --policy=lru\nheader_rewrite.so rewrite.conf\n");
auto result = config::PluginConfigParser{}.parse(tf.path());
REQUIRE(result.ok());
auto yaml = config::PluginConfigMarshaller{}.to_yaml(result.value);
YAML::Node root = YAML::Load(yaml);
REQUIRE(root["plugins"].size() == 3);
CHECK(root["plugins"][0]["path"].as<std::string>() == "stats_over_http.so");
CHECK_FALSE(root["plugins"][0]["enabled"]);
CHECK(root["plugins"][1]["path"].as<std::string>() == "cache_promote.so");
CHECK(root["plugins"][1]["enabled"].as<bool>() == false);
CHECK(root["plugins"][2]["path"].as<std::string>() == "header_rewrite.so");
CHECK_FALSE(root["plugins"][2]["enabled"]);
}