Skip to content

Commit cab4ce6

Browse files
jyotimamattklein123
authored andcommitted
Enable proto schema for router_check_tool (envoyproxy#6992)
Signed-off-by: Jyoti Mahapatra <[email protected]>
1 parent f78295b commit cab4ce6

20 files changed

+1184
-4
lines changed

docs/root/install/tools/route_table_check_tool.rst

+14-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ Input
1818
:ref:`config <config_tools_router_check_tool>`.
1919
The tool config input file specifies urls (composed of authorities and paths)
2020
and expected route parameter values. Additional parameters such as additional headers are optional.
21+
Schema: All internal schemas in the tool are based on :repo:`proto3 <test/tools/router_check/validation.proto>`.
22+
This is enabled by an extra optional parameter ``--useproto``. This parameter will become the default in the future releases and enables more validation features in the tool.
23+
Any new feature addition in validations will be added behind this parameter.
24+
Migration: If you are currently using the tool and plan to migrate to use ``--useproto``, change the yaml/json test's schema based on the :repo:`proto <test/tools/router_check/validation.proto>`.
25+
Few known changes necessary are:
26+
``:authority`` input is now ``authority``.
27+
``:path`` input is now ``path``.
28+
``:method`` input is now ``method``. This is a required property.
29+
``additional_headers`` in the input along with ``header_fields`` and ``custom_header_fields`` contain ``key`` instead of ``field``.
30+
``tests`` is a root level field in the yaml/json.
2131

2232
Output
2333
The program exits with status EXIT_FAILURE if any test case does not match the expected route parameter
@@ -52,12 +62,15 @@ Running
5262
expected order of command line arguments is:
5363
1. The router configuration file.
5464
2. The tool configuration json file.
55-
3. The optional details flag. ::
65+
3. ``--useproto`` to use any new features in the tool.
66+
4. The optional details flag. ::
5667

5768
bazel-bin/test/tools/router_check/router_check_tool router_config.(yaml|json) tool_config.json
5869

5970
bazel-bin/test/tools/router_check/router_check_tool router_config.(yaml|json) tool_config.json --details
6071

72+
bazel-bin/test/tools/router_check/router_check_tool router_config.(yaml|json) tool_config.json --details --useproto
73+
6174
Testing
6275
A bash shell script test can be run with bazel. The test compares routes using different router and
6376
tool configuration files. The configuration files can be found in

docs/root/intro/deprecated.rst

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Version 1.11.0 (Pending)
1414
========================
1515
* The --max-stats and --max-obj-name-len flags no longer has any effect.
1616
* Use of :ref:`cluster <envoy_api_field_config.filter.network.redis_proxy.v2.RedisProxy.cluster>` in :ref:`redis_proxy.proto <envoy_api_file_envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto>` is deprecated. Set a :ref:`catch_all_cluster <envoy_api_field_config.filter.network.redis_proxy.v2.RedisProxy.PrefixRoutes.catch_all_cluster>` instead.
17+
* Use of json based schema in router check tool tests. The tests should follow validation :repo:`schema<test/tools/router_check/validation.proto>`.
1718

1819
Version 1.10.0 (Apr 5, 2019)
1920
============================

docs/root/intro/version_history.rst

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Version history
3838
* sandbox: added :ref:`CSRF sandbox <install_sandboxes_csrf>`.
3939
* server: ``--define manual_stamp=manual_stamp`` was added to allow server stamping outside of binary rules.
4040
more info in the `bazel docs <https://github.com/envoyproxy/envoy/blob/master/bazel/README.md#enabling-optional-features>`_.
41+
* tool: added :repo:`proto <test/tools/router_check/validation.proto>` support for :ref:`router check tool <install_tools_route_table_check_tool>` tests.
4142
* upstream: added :ref:`upstream_cx_pool_overflow <config_cluster_manager_cluster_stats>` for the connection pool circuit breaker.
4243
* upstream: an EDS management server can now force removal of a host that is still passing active
4344
health checking by first marking the host as failed via EDS health check and subsequently removing

test/tools/router_check/BUILD

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ load(
55
"envoy_cc_test_binary",
66
"envoy_cc_test_library",
77
"envoy_package",
8+
"envoy_proto_library",
89
)
910

1011
envoy_package()
@@ -22,6 +23,7 @@ envoy_cc_test_library(
2223
"router.h",
2324
],
2425
deps = [
26+
":validation_proto_cc",
2527
"//source/common/config:rds_json_lib",
2628
"//source/common/event:dispatcher_lib",
2729
"//source/common/http:header_map_lib",
@@ -35,3 +37,9 @@ envoy_cc_test_library(
3537
"//test/tools/router_check/json:tool_config_schemas_lib",
3638
],
3739
)
40+
41+
envoy_proto_library(
42+
name = "validation_proto",
43+
srcs = ["validation.proto"],
44+
deps = ["@envoy_api//envoy/api/v2/core:base_export"],
45+
)

test/tools/router_check/router.cc

+158
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,28 @@ ToolConfig ToolConfig::create(const Json::ObjectSharedPtr check_config) {
3737
return ToolConfig(std::move(headers), random_value);
3838
}
3939

40+
ToolConfig ToolConfig::create(const envoy::RouterCheckToolSchema::ValidationItem& check_config) {
41+
// Add header field values
42+
std::unique_ptr<Http::TestHeaderMapImpl> headers(new Http::TestHeaderMapImpl());
43+
headers->addCopy(":authority", check_config.input().authority());
44+
headers->addCopy(":path", check_config.input().path());
45+
headers->addCopy(":method", check_config.input().method());
46+
headers->addCopy("x-forwarded-proto", check_config.input().ssl() ? "https" : "http");
47+
48+
if (check_config.input().internal()) {
49+
headers->addCopy("x-envoy-internal", "true");
50+
}
51+
52+
if (check_config.input().additional_headers().data()) {
53+
for (const envoy::api::v2::core::HeaderValue& header_config :
54+
check_config.input().additional_headers()) {
55+
headers->addCopy(header_config.key(), header_config.value());
56+
}
57+
}
58+
59+
return ToolConfig(std::move(headers), check_config.input().random_value());
60+
}
61+
4062
ToolConfig::ToolConfig(std::unique_ptr<Http::TestHeaderMapImpl> headers, int random_value)
4163
: headers_(std::move(headers)), random_value_(random_value) {}
4264

@@ -130,6 +152,50 @@ bool RouterCheckTool::compareEntriesInJson(const std::string& expected_route_jso
130152
return no_failures;
131153
}
132154

155+
bool RouterCheckTool::compareEntries(const std::string& expected_routes) {
156+
envoy::RouterCheckToolSchema::Validation validation_config;
157+
auto stats = std::make_unique<Stats::IsolatedStoreImpl>();
158+
auto api = Api::createApiForTest(*stats);
159+
const std::string contents = api->fileSystem().fileReadToEnd(expected_routes);
160+
MessageUtil::loadFromFile(expected_routes, validation_config, *api);
161+
MessageUtil::validate(validation_config);
162+
163+
bool no_failures = true;
164+
for (const envoy::RouterCheckToolSchema::ValidationItem& check_config :
165+
validation_config.tests()) {
166+
ToolConfig tool_config = ToolConfig::create(check_config);
167+
tool_config.route_ = config_->route(*tool_config.headers_, tool_config.random_value_);
168+
169+
std::string test_name = check_config.test_name();
170+
if (details_) {
171+
std::cout << test_name << std::endl;
172+
}
173+
envoy::RouterCheckToolSchema::ValidationAssert validate = check_config.validate();
174+
175+
using checkerFunc =
176+
std::function<bool(ToolConfig&, const envoy::RouterCheckToolSchema::ValidationAssert&)>;
177+
checkerFunc checkers[] = {
178+
[this](auto&... params) -> bool { return this->compareCluster(params...); },
179+
[this](auto&... params) -> bool { return this->compareVirtualCluster(params...); },
180+
[this](auto&... params) -> bool { return this->compareVirtualHost(params...); },
181+
[this](auto&... params) -> bool { return this->compareRewritePath(params...); },
182+
[this](auto&... params) -> bool { return this->compareRewriteHost(params...); },
183+
[this](auto&... params) -> bool { return this->compareRedirectPath(params...); },
184+
[this](auto&... params) -> bool { return this->compareHeaderField(params...); },
185+
[this](auto&... params) -> bool { return this->compareCustomHeaderField(params...); },
186+
};
187+
188+
// Call appropriate function for each match case.
189+
for (const auto& test : checkers) {
190+
if (!test(tool_config, validate)) {
191+
no_failures = false;
192+
}
193+
}
194+
}
195+
196+
return no_failures;
197+
}
198+
133199
bool RouterCheckTool::compareCluster(ToolConfig& tool_config, const std::string& expected) {
134200
std::string actual = "";
135201

@@ -139,6 +205,17 @@ bool RouterCheckTool::compareCluster(ToolConfig& tool_config, const std::string&
139205
return compareResults(actual, expected, "cluster_name");
140206
}
141207

208+
bool RouterCheckTool::compareCluster(
209+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
210+
if (expected.cluster_name().empty()) {
211+
return true;
212+
}
213+
if (tool_config.route_ == nullptr) {
214+
return compareResults("", expected.cluster_name(), "cluster_name");
215+
}
216+
return compareCluster(tool_config, expected.cluster_name());
217+
}
218+
142219
bool RouterCheckTool::compareVirtualCluster(ToolConfig& tool_config, const std::string& expected) {
143220
std::string actual = "";
144221

@@ -151,6 +228,17 @@ bool RouterCheckTool::compareVirtualCluster(ToolConfig& tool_config, const std::
151228
return compareResults(actual, expected, "virtual_cluster_name");
152229
}
153230

231+
bool RouterCheckTool::compareVirtualCluster(
232+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
233+
if (expected.virtual_cluster_name().empty()) {
234+
return true;
235+
}
236+
if (tool_config.route_ == nullptr) {
237+
return compareResults("", expected.virtual_cluster_name(), "virtual_cluster_name");
238+
}
239+
return compareVirtualCluster(tool_config, expected.virtual_cluster_name());
240+
}
241+
154242
bool RouterCheckTool::compareVirtualHost(ToolConfig& tool_config, const std::string& expected) {
155243
std::string actual = "";
156244
if (tool_config.route_->routeEntry() != nullptr) {
@@ -160,6 +248,17 @@ bool RouterCheckTool::compareVirtualHost(ToolConfig& tool_config, const std::str
160248
return compareResults(actual, expected, "virtual_host_name");
161249
}
162250

251+
bool RouterCheckTool::compareVirtualHost(
252+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
253+
if (expected.virtual_host_name().empty()) {
254+
return true;
255+
}
256+
if (tool_config.route_ == nullptr) {
257+
return compareResults("", expected.virtual_host_name(), "virtual_host_name");
258+
}
259+
return compareVirtualHost(tool_config, expected.virtual_host_name());
260+
}
261+
163262
bool RouterCheckTool::compareRewritePath(ToolConfig& tool_config, const std::string& expected) {
164263
std::string actual = "";
165264
Envoy::StreamInfo::StreamInfoImpl stream_info(Envoy::Http::Protocol::Http11,
@@ -172,6 +271,17 @@ bool RouterCheckTool::compareRewritePath(ToolConfig& tool_config, const std::str
172271
return compareResults(actual, expected, "path_rewrite");
173272
}
174273

274+
bool RouterCheckTool::compareRewritePath(
275+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
276+
if (expected.path_rewrite().empty()) {
277+
return true;
278+
}
279+
if (tool_config.route_ == nullptr) {
280+
return compareResults("", expected.path_rewrite(), "path_rewrite");
281+
}
282+
return compareRewritePath(tool_config, expected.path_rewrite());
283+
}
284+
175285
bool RouterCheckTool::compareRewriteHost(ToolConfig& tool_config, const std::string& expected) {
176286
std::string actual = "";
177287
Envoy::StreamInfo::StreamInfoImpl stream_info(Envoy::Http::Protocol::Http11,
@@ -184,6 +294,17 @@ bool RouterCheckTool::compareRewriteHost(ToolConfig& tool_config, const std::str
184294
return compareResults(actual, expected, "host_rewrite");
185295
}
186296

297+
bool RouterCheckTool::compareRewriteHost(
298+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
299+
if (expected.host_rewrite().empty()) {
300+
return true;
301+
}
302+
if (tool_config.route_ == nullptr) {
303+
return compareResults("", expected.host_rewrite(), "host_rewrite");
304+
}
305+
return compareRewriteHost(tool_config, expected.host_rewrite());
306+
}
307+
187308
bool RouterCheckTool::compareRedirectPath(ToolConfig& tool_config, const std::string& expected) {
188309
std::string actual = "";
189310
if (tool_config.route_->directResponseEntry() != nullptr) {
@@ -193,6 +314,30 @@ bool RouterCheckTool::compareRedirectPath(ToolConfig& tool_config, const std::st
193314
return compareResults(actual, expected, "path_redirect");
194315
}
195316

317+
bool RouterCheckTool::compareRedirectPath(
318+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
319+
if (expected.path_redirect().empty()) {
320+
return true;
321+
}
322+
if (tool_config.route_ == nullptr) {
323+
return compareResults("", expected.path_redirect(), "path_redirect");
324+
}
325+
return compareRedirectPath(tool_config, expected.path_redirect());
326+
}
327+
328+
bool RouterCheckTool::compareHeaderField(
329+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
330+
bool no_failures = true;
331+
if (expected.header_fields().data()) {
332+
for (const envoy::api::v2::core::HeaderValue& header : expected.header_fields()) {
333+
if (!compareHeaderField(tool_config, header.key(), header.value())) {
334+
no_failures = false;
335+
}
336+
}
337+
}
338+
return no_failures;
339+
}
340+
196341
bool RouterCheckTool::compareHeaderField(ToolConfig& tool_config, const std::string& field,
197342
const std::string& expected) {
198343
std::string actual = tool_config.headers_->get_(field);
@@ -213,6 +358,19 @@ bool RouterCheckTool::compareCustomHeaderField(ToolConfig& tool_config, const st
213358
return compareResults(actual, expected, "custom_header");
214359
}
215360

361+
bool RouterCheckTool::compareCustomHeaderField(
362+
ToolConfig& tool_config, const envoy::RouterCheckToolSchema::ValidationAssert& expected) {
363+
bool no_failures = true;
364+
if (expected.custom_header_fields().data()) {
365+
for (const envoy::api::v2::core::HeaderValue& header : expected.custom_header_fields()) {
366+
if (!compareCustomHeaderField(tool_config, header.key(), header.value())) {
367+
no_failures = false;
368+
}
369+
}
370+
}
371+
return no_failures;
372+
}
373+
216374
bool RouterCheckTool::compareResults(const std::string& actual, const std::string& expected,
217375
const std::string& test_type) {
218376
if (expected == actual) {

test/tools/router_check/router.h

+33
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <memory>
44
#include <string>
55

6+
#include "envoy/api/v2/core/base.pb.h"
7+
68
#include "common/common/logger.h"
79
#include "common/common/utility.h"
810
#include "common/http/header_map_impl.h"
@@ -16,6 +18,8 @@
1618
#include "test/test_common/printers.h"
1719
#include "test/test_common/utility.h"
1820
#include "test/tools/router_check/json/tool_config_schemas.h"
21+
#include "test/tools/router_check/validation.pb.h"
22+
#include "test/tools/router_check/validation.pb.validate.h"
1923

2024
namespace Envoy {
2125
/**
@@ -32,6 +36,13 @@ struct ToolConfig {
3236
*/
3337
static ToolConfig create(const Json::ObjectSharedPtr check_config);
3438

39+
/**
40+
* @param check_config tool config proto object.
41+
* @return ToolConfig a ToolConfig instance with member variables set by the tool config json
42+
* file.
43+
*/
44+
static ToolConfig create(const envoy::RouterCheckToolSchema::ValidationItem& check_config);
45+
3546
Stats::SymbolTable& symbolTable() { return *symbol_table_; }
3647

3748
std::unique_ptr<Http::TestHeaderMapImpl> headers_;
@@ -64,6 +75,12 @@ class RouterCheckTool : Logger::Loggable<Logger::Id::testing> {
6475
*/
6576
bool compareEntriesInJson(const std::string& expected_route_json);
6677

78+
/**
79+
* @param expected_route_json tool config json file.
80+
* @return bool if all routes match what is expected.
81+
*/
82+
bool compareEntries(const std::string& expected_routes);
83+
6784
/**
6885
* Set whether to print out match case details.
6986
*/
@@ -76,15 +93,31 @@ class RouterCheckTool : Logger::Loggable<Logger::Id::testing> {
7693
Api::ApiPtr api);
7794

7895
bool compareCluster(ToolConfig& tool_config, const std::string& expected);
96+
bool compareCluster(ToolConfig& tool_config,
97+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
7998
bool compareVirtualCluster(ToolConfig& tool_config, const std::string& expected);
99+
bool compareVirtualCluster(ToolConfig& tool_config,
100+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
80101
bool compareVirtualHost(ToolConfig& tool_config, const std::string& expected);
102+
bool compareVirtualHost(ToolConfig& tool_config,
103+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
81104
bool compareRewriteHost(ToolConfig& tool_config, const std::string& expected);
105+
bool compareRewriteHost(ToolConfig& tool_config,
106+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
82107
bool compareRewritePath(ToolConfig& tool_config, const std::string& expected);
108+
bool compareRewritePath(ToolConfig& tool_config,
109+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
83110
bool compareRedirectPath(ToolConfig& tool_config, const std::string& expected);
111+
bool compareRedirectPath(ToolConfig& tool_config,
112+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
84113
bool compareHeaderField(ToolConfig& tool_config, const std::string& field,
85114
const std::string& expected);
115+
bool compareHeaderField(ToolConfig& tool_config,
116+
const envoy::RouterCheckToolSchema::ValidationAssert& expected);
86117
bool compareCustomHeaderField(ToolConfig& tool_config, const std::string& field,
87118
const std::string& expected);
119+
bool compareCustomHeaderField(ToolConfig& tool_config,
120+
const envoy::RouterCheckToolSchema::ValidationAssert& expecte);
88121
/**
89122
* Compare the expected and actual route parameter values. Print out match details if details_
90123
* flag is set.

0 commit comments

Comments
 (0)