diff options
author | jansenin <jansenin@yandex-team.com> | 2023-09-26 14:16:19 +0300 |
---|---|---|
committer | jansenin <jansenin@yandex-team.com> | 2023-09-26 15:30:43 +0300 |
commit | a5d2f065b28f129c560fa5aefa27a1b1e9fb1364 (patch) | |
tree | ba8e838762321e073d310965f831e42f6077454e | |
parent | cec2f6710c32600fe77e72075758b490cb6e2883 (diff) | |
download | ydb-a5d2f065b28f129c560fa5aefa27a1b1e9fb1364.tar.gz |
add part of static config validator and tests for it, add some configurators
32 files changed, 1012 insertions, 5 deletions
diff --git a/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt index 53f12dbad16..1d4687f1e2f 100644 --- a/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt +++ b/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt @@ -7,6 +7,7 @@ add_subdirectory(public) +add_subdirectory(static_validator) add_subdirectory(ut) add_subdirectory(validator) diff --git a/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt index d0effadc52c..3efee2c1abe 100644 --- a/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt +++ b/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt @@ -7,6 +7,7 @@ add_subdirectory(public) +add_subdirectory(static_validator) add_subdirectory(ut) add_subdirectory(validator) diff --git a/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt index d0effadc52c..3efee2c1abe 100644 --- a/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt +++ b/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt @@ -7,6 +7,7 @@ add_subdirectory(public) +add_subdirectory(static_validator) add_subdirectory(ut) add_subdirectory(validator) diff --git a/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt index 53f12dbad16..1d4687f1e2f 100644 --- a/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt +++ b/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt @@ -7,6 +7,7 @@ add_subdirectory(public) +add_subdirectory(static_validator) add_subdirectory(ut) add_subdirectory(validator) diff --git a/ydb/library/yaml_config/static_validator/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/static_validator/CMakeLists.darwin-x86_64.txt new file mode 100644 index 00000000000..254d5ad015f --- /dev/null +++ b/ydb/library/yaml_config/static_validator/CMakeLists.darwin-x86_64.txt @@ -0,0 +1,19 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +add_subdirectory(ut) + +add_library(library-yaml_config-static_validator) +target_link_libraries(library-yaml_config-static_validator PUBLIC + contrib-libs-cxxsupp + yutil + library-yaml_config-validator +) +target_sources(library-yaml_config-static_validator PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/builders.cpp +) diff --git a/ydb/library/yaml_config/static_validator/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/static_validator/CMakeLists.linux-aarch64.txt new file mode 100644 index 00000000000..b97f4674a8e --- /dev/null +++ b/ydb/library/yaml_config/static_validator/CMakeLists.linux-aarch64.txt @@ -0,0 +1,20 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +add_subdirectory(ut) + +add_library(library-yaml_config-static_validator) +target_link_libraries(library-yaml_config-static_validator PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + library-yaml_config-validator +) +target_sources(library-yaml_config-static_validator PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/builders.cpp +) diff --git a/ydb/library/yaml_config/static_validator/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/static_validator/CMakeLists.linux-x86_64.txt new file mode 100644 index 00000000000..b97f4674a8e --- /dev/null +++ b/ydb/library/yaml_config/static_validator/CMakeLists.linux-x86_64.txt @@ -0,0 +1,20 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +add_subdirectory(ut) + +add_library(library-yaml_config-static_validator) +target_link_libraries(library-yaml_config-static_validator PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + library-yaml_config-validator +) +target_sources(library-yaml_config-static_validator PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/builders.cpp +) diff --git a/ydb/library/yaml_config/static_validator/CMakeLists.txt b/ydb/library/yaml_config/static_validator/CMakeLists.txt new file mode 100644 index 00000000000..f8b31df0c11 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/CMakeLists.txt @@ -0,0 +1,17 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-aarch64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + include(CMakeLists.darwin-x86_64.txt) +elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA) + include(CMakeLists.windows-x86_64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-x86_64.txt) +endif() diff --git a/ydb/library/yaml_config/static_validator/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/static_validator/CMakeLists.windows-x86_64.txt new file mode 100644 index 00000000000..254d5ad015f --- /dev/null +++ b/ydb/library/yaml_config/static_validator/CMakeLists.windows-x86_64.txt @@ -0,0 +1,19 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +add_subdirectory(ut) + +add_library(library-yaml_config-static_validator) +target_link_libraries(library-yaml_config-static_validator PUBLIC + contrib-libs-cxxsupp + yutil + library-yaml_config-validator +) +target_sources(library-yaml_config-static_validator PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/builders.cpp +) diff --git a/ydb/library/yaml_config/static_validator/builders.cpp b/ydb/library/yaml_config/static_validator/builders.cpp new file mode 100644 index 00000000000..e38ff01938a --- /dev/null +++ b/ydb/library/yaml_config/static_validator/builders.cpp @@ -0,0 +1,126 @@ +#include "builders.h" + +#include <ydb/library/yaml_config/validator/validator_checks.h> +#include <ydb/library/yaml_config/validator/configurators.h> + +using namespace NYamlConfig::NValidator; +using namespace NYamlConfig::NValidator::Configurators; + +TArrayBuilder HostConfigBuilder() { + return TArrayBuilder([](auto& b) {b + .Configure(uniqueByPath("host_config_id")) + .MapItem([](auto& b) {b + .Int64("host_config_id", nonNegative()) // >= 0? + .Array("drive", [](auto& b) {b + .Configure(uniqueByPath("path")) + .MapItem([](auto& b) {b + .String("path") + .Enum("type", {"ssd", "nvme", "rot"}); + }); + }); + }); + }); +} + +TArrayBuilder HostsBuilder() { + return TArrayBuilder([](auto& b){b + .MapItem([](auto& b) {b + .String("host") + .Int64("host_config_id", nonNegative()) + .Int64("node_id", nonNegative()) + .Int64("port", 0, 65535) + .Map("location", [](auto& b){b + .String("unit") + .String("data_center") + .String("rack"); + }); + }) + .Configure(uniqueByPath("node_id")) + .AddCheck("Must not have to hosts with same host name and port", [](auto& c) { + auto array = c.Node(); + THashMap<std::pair<TString, i64>, i64> itemsToIndex; + + for (int i = 0; i < array.Length(); ++i) { + TString host = array[i].Map()["host"].String(); + i64 port = array[i].Map()["port"].Int64(); + auto item = std::pair{host, port}; + + if (itemsToIndex.contains(item)) { + TString i1 = ToString(itemsToIndex[item]); + TString i2 = ToString(i); + + c.Fail("items with indexes " + i1 + " and " + i2 + " are conflicting"); + } + itemsToIndex[item] = i; + } + }); + }); +} + +TMapBuilder DomainsConfigBuilder() { + return TMapBuilder([](auto& b){b + .Array("domain", [](auto& b){b + .MapItem([](auto& b){b + .String("name") + .Field("storage_pool_types", StoragePoolTypesConfigBuilder()); + }); + }) + .Field("state_storage", StateStorageBuilder()) + .Field("security_config", SecurityConfigBuilder()); + }); +} + +TArrayBuilder StoragePoolTypesConfigBuilder() { + return TArrayBuilder([](auto& b){b + .MapItem([](auto& b){b + .String("kind") + .Map("pool_config", [](auto& b){b + .Int64("box_id", nonNegative()) + .Int64("encryption", [](auto&b){b + .Range(0, 1) + .Optional(); + }) + .Enum("erasure_species", {"none", "block-4-2", "mirror-3-dc", "mirror-3dc-3-nodes"}) + .String("kind") + .Array("pdisk_filter", [](auto& b){b + .MapItem([](auto& b){b + .Array("property", [](auto& b){b + .MapItem([](auto& b){b + .Enum("type", {"ssd", "nvme", "rot"}); + }); + }); + }); + }); + }) + .Configure(mustBeEqual("kind", "pool_config/kind")); + }); + }); +} + +TArrayBuilder StateStorageBuilder() { + return TArrayBuilder([](auto& b){b + .MapItem([](auto& b){b + .Map("ring", [](auto& b){b + .Array("node", [](auto& b){b + .Int64Item(nonNegative()); + }) + .Int64("nto_select", nonNegative()) + .AddCheck("nto_select must not be greater, than node array size", [](auto& c){ + i64 nto_select = c.Node()["nto_select"].Int64(); + i64 arr_size = c.Node()["node"].Array().Length(); + c.Expect(nto_select <= arr_size); + }); + }) + .Int64("ssid", nonNegative()); + }); + }); +} + +TMapBuilder SecurityConfigBuilder() { + return TMapBuilder([](auto& b){b + .Bool("enforce_user_token_requirement", [](auto& b){ + b.Optional(); + }) + .Optional(); + }); +} diff --git a/ydb/library/yaml_config/static_validator/builders.h b/ydb/library/yaml_config/static_validator/builders.h new file mode 100644 index 00000000000..ec81eaa42e9 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/builders.h @@ -0,0 +1,9 @@ +#include <ydb/library/yaml_config/validator/validator_builder.h> + +NYamlConfig::NValidator::TArrayBuilder HostConfigBuilder(); +NYamlConfig::NValidator::TArrayBuilder HostsBuilder(); +NYamlConfig::NValidator::TMapBuilder DomainsConfigBuilder(); + +NYamlConfig::NValidator::TArrayBuilder StoragePoolTypesConfigBuilder(); +NYamlConfig::NValidator::TArrayBuilder StateStorageBuilder(); +NYamlConfig::NValidator::TMapBuilder SecurityConfigBuilder(); diff --git a/ydb/library/yaml_config/static_validator/ut/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/static_validator/ut/CMakeLists.darwin-x86_64.txt new file mode 100644 index 00000000000..5ba673b5a07 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/CMakeLists.darwin-x86_64.txt @@ -0,0 +1,63 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(ydb-library-yaml_config-static_validator-ut) +target_link_libraries(ydb-library-yaml_config-static_validator-ut PUBLIC + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + library-yaml_config-static_validator + library-yaml_config-validator +) +target_link_options(ydb-library-yaml_config-static_validator-ut PRIVATE + -Wl,-platform_version,macos,11.0,11.0 + -fPIC + -fPIC +) +target_sources(ydb-library-yaml_config-static_validator-ut PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/ut/test.cpp +) +set_property( + TARGET + ydb-library-yaml_config-static_validator-ut + PROPERTY + SPLIT_FACTOR + 1 +) +add_yunittest( + NAME + ydb-library-yaml_config-static_validator-ut + TEST_TARGET + ydb-library-yaml_config-static_validator-ut + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + LABELS + SMALL +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + PROCESSORS + 1 +) +target_allocator(ydb-library-yaml_config-static_validator-ut + system_allocator +) +vcs_info(ydb-library-yaml_config-static_validator-ut) diff --git a/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-aarch64.txt new file mode 100644 index 00000000000..2cc2a1d91e7 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-aarch64.txt @@ -0,0 +1,68 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(ydb-library-yaml_config-static_validator-ut) +target_link_libraries(ydb-library-yaml_config-static_validator-ut PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + cpp-testing-unittest_main + library-yaml_config-static_validator + library-yaml_config-validator +) +target_link_options(ydb-library-yaml_config-static_validator-ut PRIVATE + -ldl + -lrt + -Wl,--no-as-needed + -fPIC + -fPIC + -lpthread + -lrt + -ldl +) +target_sources(ydb-library-yaml_config-static_validator-ut PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/ut/test.cpp +) +set_property( + TARGET + ydb-library-yaml_config-static_validator-ut + PROPERTY + SPLIT_FACTOR + 1 +) +add_yunittest( + NAME + ydb-library-yaml_config-static_validator-ut + TEST_TARGET + ydb-library-yaml_config-static_validator-ut + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + LABELS + SMALL +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + PROCESSORS + 1 +) +target_allocator(ydb-library-yaml_config-static_validator-ut + cpp-malloc-jemalloc +) +vcs_info(ydb-library-yaml_config-static_validator-ut) diff --git a/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-x86_64.txt new file mode 100644 index 00000000000..ab86023928e --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/CMakeLists.linux-x86_64.txt @@ -0,0 +1,70 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(ydb-library-yaml_config-static_validator-ut) +target_link_libraries(ydb-library-yaml_config-static_validator-ut PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + library-yaml_config-static_validator + library-yaml_config-validator +) +target_link_options(ydb-library-yaml_config-static_validator-ut PRIVATE + -ldl + -lrt + -Wl,--no-as-needed + -fPIC + -fPIC + -lpthread + -lrt + -ldl +) +target_sources(ydb-library-yaml_config-static_validator-ut PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/ut/test.cpp +) +set_property( + TARGET + ydb-library-yaml_config-static_validator-ut + PROPERTY + SPLIT_FACTOR + 1 +) +add_yunittest( + NAME + ydb-library-yaml_config-static_validator-ut + TEST_TARGET + ydb-library-yaml_config-static_validator-ut + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + LABELS + SMALL +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + PROCESSORS + 1 +) +target_allocator(ydb-library-yaml_config-static_validator-ut + cpp-malloc-tcmalloc + libs-tcmalloc-no_percpu_cache +) +vcs_info(ydb-library-yaml_config-static_validator-ut) diff --git a/ydb/library/yaml_config/static_validator/ut/CMakeLists.txt b/ydb/library/yaml_config/static_validator/ut/CMakeLists.txt new file mode 100644 index 00000000000..f8b31df0c11 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/CMakeLists.txt @@ -0,0 +1,17 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-aarch64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + include(CMakeLists.darwin-x86_64.txt) +elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA) + include(CMakeLists.windows-x86_64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-x86_64.txt) +endif() diff --git a/ydb/library/yaml_config/static_validator/ut/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/static_validator/ut/CMakeLists.windows-x86_64.txt new file mode 100644 index 00000000000..749e97fd3c5 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/CMakeLists.windows-x86_64.txt @@ -0,0 +1,58 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(ydb-library-yaml_config-static_validator-ut) +target_link_libraries(ydb-library-yaml_config-static_validator-ut PUBLIC + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + library-yaml_config-static_validator + library-yaml_config-validator +) +target_sources(ydb-library-yaml_config-static_validator-ut PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/static_validator/ut/test.cpp +) +set_property( + TARGET + ydb-library-yaml_config-static_validator-ut + PROPERTY + SPLIT_FACTOR + 1 +) +add_yunittest( + NAME + ydb-library-yaml_config-static_validator-ut + TEST_TARGET + ydb-library-yaml_config-static_validator-ut + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + LABELS + SMALL +) +set_yunittest_property( + TEST + ydb-library-yaml_config-static_validator-ut + PROPERTY + PROCESSORS + 1 +) +target_allocator(ydb-library-yaml_config-static_validator-ut + system_allocator +) +vcs_info(ydb-library-yaml_config-static_validator-ut) diff --git a/ydb/library/yaml_config/static_validator/ut/test.cpp b/ydb/library/yaml_config/static_validator/ut/test.cpp new file mode 100644 index 00000000000..555634e1e90 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/test.cpp @@ -0,0 +1,318 @@ +#include <ydb/library/yaml_config/static_validator/builders.h> + +#include <library/cpp/testing/unittest/registar.h> +#include <ydb/library/yaml_config/validator/validator.h> +#include <ydb/library/yaml_config/validator/validator_builder.h> + +using namespace NYamlConfig::NValidator; +using TIssue = TValidationResult::TIssue; + +bool HasOnlyThisIssues(TValidationResult result, TVector<TIssue> issues) { + if (result.Issues.size() != issues.size()) { + Cerr << "Issue counts are differend. List of actul issues:" << Endl; + Cerr << result; + Cerr << "------------- List of Expected Issues: " << Endl; + Cerr << TValidationResult(issues); + Cerr << "------------- End of issue List" << Endl; + return false; + } + Sort(result.Issues); + Sort(issues); + for (size_t i = 0; i < issues.size(); ++i) { + if (result.Issues[i] != issues[i]) { + Cerr << "Issues are differend. List of actul issues:" << Endl; + Cerr << result; + Cerr << "------------- List of Expected Issues: " << Endl; + Cerr << TValidationResult(issues); + Cerr << "------------- End of issue List" << Endl; + return false; + } + } + return true; +} + +bool Valid(TValidationResult result) { + if (result.Ok()) return true; + + Cerr << "List of issues:" << Endl; + Cerr << result; + Cerr << "------------- End of issue list: " << Endl; + return false; +} + +Y_UNIT_TEST_SUITE(StaticValidator) { + Y_UNIT_TEST(HostConfigs) { + auto v = + TMapBuilder() + .Field("host_configs", HostConfigBuilder()) + .CreateValidator(); + + auto yaml = + "host_configs:\n" + "- host_config_id: 1\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n"; + + Y_ENSURE(Valid(v.Validate(yaml))); + + yaml = + "host_configs:\n" + "- host_config_id: 1\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + "- host_config_id: 2\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_03\n" + " type: SSD\n"; + + Y_ENSURE(Valid(v.Validate(yaml))); + + yaml = + "host_configs:\n" + "- host_config_id: 1\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + "- host_config_id: 1\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_03\n" + " type: SSD\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/host_configs", "Check \"All array items, that located in \"host_config_id\" must be unique\" failed: items with indexes 0 and 1 are conflicting"} + })); + + yaml = + "host_configs:\n" + "- host_config_id: 1\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + "- host_config_id: 2\n" + " drive:\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_02\n" + " type: SSD\n" + " - path: /dev/disk/by-partlabel/ydb_disk_ssd_01\n" + " type: SSD\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/host_configs/1/drive", "Check \"All array items, that located in \"path\" must be unique\" failed: items with indexes 0 and 2 are conflicting"} + })); + } + + Y_UNIT_TEST(Hosts) { + auto v = + TMapBuilder() + .Field("hosts", HostsBuilder()) + .CreateValidator(); + + auto yaml = + "hosts:\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n" + "- host: hostname2\n" + " host_config_id: 1\n" + " node_id: 2\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n"; + + Y_ENSURE(Valid(v.Validate(yaml))); + + yaml = + "hosts:\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 2\n" + " port: 19002\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n"; + + Y_ENSURE(Valid(v.Validate(yaml))); + + yaml = + "hosts:\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 2\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/hosts", "Check \"Must not have to hosts with same host name and port\" failed: items with indexes 0 and 1 are conflicting"} + })); + + yaml = + "hosts:\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/hosts", "Check \"All array items, that located in \"node_id\" must be unique\" failed: items with indexes 0 and 1 are conflicting"}, + {"/hosts", "Check \"Must not have to hosts with same host name and port\" failed: items with indexes 0 and 1 are conflicting"} + })); + + yaml = + "hosts:\n" + "- host: hostname1\n" + " host_config_id: 1\n" + " node_id: 1\n" + " port: 19001\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n" + "- host: hostname2\n" + " host_config_id: 1\n" + " node_id: 2\n" + " port: 65536\n" + " location:\n" + " unit: '1'\n" + " data_center: '1'\n" + " rack: '1'\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/hosts/1/port", "Value must be less or equal to max value(i.e <= 65535)"} + })); + } + + Y_UNIT_TEST(DomainsConfig) { + auto v = + TMapBuilder() + .Field("domains_config", DomainsConfigBuilder()) + .CreateValidator(); + + auto yaml = + "domains_config:\n" + " domain:\n" + " - name: Root\n" + " storage_pool_types:\n" + " - kind: ssd\n" + " pool_config:\n" + " box_id: 1\n" + " erasure_species: block-4-2\n" + " kind: ssd\n" + " pdisk_filter:\n" + " - property:\n" + " - type: SSD\n" + " vdisk_kind: Default\n" + " state_storage:\n" + " - ring:\n" + " node: [1, 2, 3, 4, 5, 6, 7, 8]\n" + " nto_select: 8\n" + " ssid: 1\n" + " security_config:\n" + " enforce_user_token_requirement: true\n"; + + Y_ENSURE(Valid(v.Validate(yaml))); + + yaml = + "domains_config:\n" + " domain:\n" + " - name: Root\n" + " storage_pool_types:\n" + " - kind: ssd\n" + " pool_config:\n" + " box_id: 1\n" + " erasure_species: block-4-2\n" + " kind: aaaaaaaaa\n" + " pdisk_filter:\n" + " - property:\n" + " - type: SSD\n" + " vdisk_kind: Default\n" + " state_storage:\n" + " - ring:\n" + " node: [1, 2, 3, 4, 5, 6, 7, 8]\n" + " nto_select: 8\n" + " ssid: 1\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/domains_config/domain/0/storage_pool_types/0", "Fields with paths kind and pool_config/kind must be equal"} + })); + + yaml = + "domains_config:\n" + " domain:\n" + " - name: Root\n" + " storage_pool_types:\n" + " - kind: ssd\n" + " pool_config:\n" + " box_id: 1\n" + " erasure_species: block-4-2\n" + " kind: ssd\n" + " pdisk_filter:\n" + " - property:\n" + " - type: SSD\n" + " vdisk_kind: Default\n" + " state_storage:\n" + " - ring:\n" + " node: [1, 2, 3, 4, 5, 6, 7, 8]\n" + " nto_select: 9\n" + " ssid: 1\n"; + + Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), { + {"/domains_config/state_storage/0/ring", "nto_select must not be greater, than node array size"} + })); + } +} diff --git a/ydb/library/yaml_config/static_validator/ut/ya.make b/ydb/library/yaml_config/static_validator/ut/ya.make new file mode 100644 index 00000000000..edb78a7fdd7 --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ut/ya.make @@ -0,0 +1,12 @@ +UNITTEST() + +SRCS( + test.cpp +) + +PEERDIR( + ydb/library/yaml_config/static_validator + ydb/library/yaml_config/validator +) + +END() diff --git a/ydb/library/yaml_config/static_validator/ya.make b/ydb/library/yaml_config/static_validator/ya.make new file mode 100644 index 00000000000..f91f00f2ade --- /dev/null +++ b/ydb/library/yaml_config/static_validator/ya.make @@ -0,0 +1,14 @@ +LIBRARY() + +PEERDIR( + ydb/library/yaml_config/validator +) + +SRCS( + builders.h + builders.cpp +) + +END() + +RECURSE_FOR_TESTS(ut)
\ No newline at end of file diff --git a/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt index a37fdfda690..2dd6b97814c 100644 --- a/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt +++ b/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt @@ -25,6 +25,7 @@ target_sources(library-yaml_config-validator PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_checks.cpp + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/configurators.cpp ) generate_enum_serilization(library-yaml_config-validator ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h diff --git a/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt index 363ef68c45e..6986c458be2 100644 --- a/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt +++ b/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt @@ -26,6 +26,7 @@ target_sources(library-yaml_config-validator PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_checks.cpp + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/configurators.cpp ) generate_enum_serilization(library-yaml_config-validator ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h diff --git a/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt index 363ef68c45e..6986c458be2 100644 --- a/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt +++ b/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt @@ -26,6 +26,7 @@ target_sources(library-yaml_config-validator PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_checks.cpp + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/configurators.cpp ) generate_enum_serilization(library-yaml_config-validator ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h diff --git a/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt index a37fdfda690..2dd6b97814c 100644 --- a/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt +++ b/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt @@ -25,6 +25,7 @@ target_sources(library-yaml_config-validator PRIVATE ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_checks.cpp + ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/configurators.cpp ) generate_enum_serilization(library-yaml_config-validator ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h diff --git a/ydb/library/yaml_config/validator/configurators.cpp b/ydb/library/yaml_config/validator/configurators.cpp new file mode 100644 index 00000000000..cd9529f9283 --- /dev/null +++ b/ydb/library/yaml_config/validator/configurators.cpp @@ -0,0 +1,80 @@ +#include "configurators.h" + +#include <ydb/library/yaml_config/validator/validator_builder.h> +#include <ydb/library/yaml_config/validator/validator_checks.h> + +#include <util/string/split.h> +#include <util/generic/hash.h> + +using namespace NYamlConfig::NValidator; + +namespace NYamlConfig::NValidator { +namespace Configurators { + +std::function<void(TInt64Builder&)> nonNegative() { + return [](auto& b) { + b.Min(0); + }; +} + +std::function<void(TArrayBuilder&)> uniqueByPath(TString path, TString checkName) { + checkName = (checkName == "") ? ("All array items, that located in \"" + path + "\" must be unique") : checkName; + return [=](auto& b) { + b.AddCheck(checkName, [=](auto& c) { + TArrayNodeWrapper array = c.Node(); + THashMap<TString, i64> valueToIndex; + + TVector<TString> pathTokens = StringSplitter(path).Split('/'); + for (int i = 0; i < array.Length(); ++i) { + TNodeWrapper node = array[i]; + node = walkFrom(node, pathTokens); + if (!node.IsScalar()) { + ythrow yexception() << "Can't check uniqness of non-scalar fields"; + } + TString value = node.Scalar(); + if (valueToIndex.contains(value)) { + TString i1 = ToString(valueToIndex[value]); + TString i2 = ToString(i); + c.Fail("items with indexes " + i1 + " and " + i2 + " are conflicting"); + } + valueToIndex[value] = i; + } + }); + }; +} + +std::function<void(TMapBuilder&)> mustBeEqual(TString path1, TString path2) { + return [=](auto& b){ + b.AddCheck("Fields with paths " + path1 + " and " + path2 +" must be equal", [=](auto& c){ + auto node1 = walkFrom(c.Node(), path1); + auto node2 = walkFrom(c.Node(), path2); + + c.Expect(node1.Scalar() == node2.Scalar()); + }); + }; +} + +} // namespace Configurators + +TNodeWrapper walkFrom(TNodeWrapper node, TString path) { + return walkFrom(node, TVector<TString>(StringSplitter(path).Split('/'))); +} + +TNodeWrapper walkFrom(TNodeWrapper node, const TVector<TString>& pathTokens) { + for (const TString& pathToken : pathTokens) { + if (node.IsMap()) { + node = node.Map()[pathToken]; + } else if (node.IsArray()) { + auto i = TryFromString<size_t>(pathToken); + if (!i.Defined()) { + ythrow yexception() << "incorrect array index"; + } + node = node.Array()[i.GetRef()]; + } else { + ythrow yexception() << "incorrect path"; + } + } + return node; +} + +} // namespace NYamlConfig::NValidator diff --git a/ydb/library/yaml_config/validator/configurators.h b/ydb/library/yaml_config/validator/configurators.h new file mode 100644 index 00000000000..15b54be16e7 --- /dev/null +++ b/ydb/library/yaml_config/validator/configurators.h @@ -0,0 +1,31 @@ +#include <ydb/library/yaml_config/validator/validator_builder.h> + +namespace NYamlConfig::NValidator { +namespace Configurators { + +std::function<void(TInt64Builder&)> nonNegative(); + +std::function<void(TArrayBuilder&)> uniqueByPath(TString path, TString checkName = ""); + +std::function<void(TMapBuilder&)> mustBeEqual(TString path1, TString path2); + +template<typename Builder> +std::function<void(Builder&)> combine(std::function<void(Builder&)> configurator) { + return configurator; +} + +template<typename Builder, typename ...Builders> +std::function<void(Builder&)> combine( + std::function<void(Builder&)> configurator, + std::function<void(Builders)>... configurators) { + return [configurator, remain = combine(configurators...)](Builder& b) { + b.Configure(configurator).Configure(remain); + }; +} + +} // namespace Configurators + +TNodeWrapper walkFrom(TNodeWrapper node, TString path); +TNodeWrapper walkFrom(TNodeWrapper node, const TVector<TString>& pathTokens); + +} // namespace NYamlConfig::NValidator diff --git a/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp index 2c9e4333e87..a04f05e6dbc 100644 --- a/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp +++ b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp @@ -276,7 +276,8 @@ Y_UNIT_TEST_SUITE(Validator) { Y_UNIT_TEST(OpaqueMaps) { auto b = TMapBuilder() - .Int64("int"); + .Int64("int") + .NotOpaque(); auto notOpaque = b.CreateValidator(); diff --git a/ydb/library/yaml_config/validator/validator.cpp b/ydb/library/yaml_config/validator/validator.cpp index f9bda449ab8..27a5ef2911a 100644 --- a/ydb/library/yaml_config/validator/validator.cpp +++ b/ydb/library/yaml_config/validator/validator.cpp @@ -253,8 +253,24 @@ TValidationResult TArrayValidator::Validate(const TNodeRef& node) { validationResult.AddValidationErrors(ItemValidatorPtr_->Validate(item)); } - // TODO: check uniqueness - Y_UNUSED(Unique_); + THashMap<TString, size_t> valueToIndex; + if (Unique_) { + for (size_t i = 0; i < node.Sequence().size(); ++i) { + const auto& item = node.Sequence()[i]; + if (item.Type() != NFyaml::ENodeType::Scalar) { + ythrow yexception() << "Can't check uniqueness of non-scalar fields"; + } + TString value = item.Scalar(); + if (valueToIndex.contains(value)) { + TString i1 = ToString(valueToIndex[value]); + TString i2 = ToString(i); + validationResult.AddIssue({ + node.Path(), + "items with indexes " + i1 + " and " + i2 + " are conflicting"}); + } + valueToIndex[value] = i; + } + } if (validationResult.Ok()) { performChecks(validationResult, node); @@ -391,7 +407,9 @@ TValidationResult TEnumValidator::Validate(const TNodeRef& node) { TValidationResult validationResult; - if (!Items_.contains(node.Scalar())) { + TString value = node.Scalar(); + value.to_lower(); + if (!Items_.contains(value)) { TString variants = JoinStrings(Items_.begin(), Items_.end(), ", "); validationResult.Issues.push_back({ diff --git a/ydb/library/yaml_config/validator/validator_builder.h b/ydb/library/yaml_config/validator/validator_builder.h index a2b6f8d7416..0cee26aa2a9 100644 --- a/ydb/library/yaml_config/validator/validator_builder.h +++ b/ydb/library/yaml_config/validator/validator_builder.h @@ -146,7 +146,7 @@ public: private: THashMap<TString, TSimpleSharedPtr<TBuilder>> Children_; - bool Opaque_ = false; + bool Opaque_ = true; void ThrowIfAlreadyHasField(const TString& field); }; diff --git a/ydb/library/yaml_config/validator/validator_checks.cpp b/ydb/library/yaml_config/validator/validator_checks.cpp index dbb6e175276..6aa6a021edf 100644 --- a/ydb/library/yaml_config/validator/validator_checks.cpp +++ b/ydb/library/yaml_config/validator/validator_checks.cpp @@ -178,6 +178,13 @@ TEnumNodeWrapper TNodeWrapper::Enum() { PathFromCheckNode_); } +TString TNodeWrapper::Scalar() { + if (!IsScalar()) { + throw TCheckException() << "Node " + Node_.Path() + " must be a scalar"; + } + return Node_.Scalar(); +} + TMaybe<ENodeType> TNodeWrapper::ValidatorType() { ThrowIfNullNode(); return NodeType_; diff --git a/ydb/library/yaml_config/validator/validator_checks.h b/ydb/library/yaml_config/validator/validator_checks.h index 57be08bf894..e14b54d0461 100644 --- a/ydb/library/yaml_config/validator/validator_checks.h +++ b/ydb/library/yaml_config/validator/validator_checks.h @@ -34,6 +34,8 @@ template <typename TThis> class TNodeWrapperCommonOps { public: TNodeWrapperCommonOps(TCheckContext& context, NFyaml::TNodeRef node, TString pathFromCheckNode); + TNodeWrapperCommonOps(const TNodeWrapperCommonOps<TThis>& other); + bool Exists() const; TNodeWrapperCommonOps<TThis>& operator=(const TNodeWrapperCommonOps<TThis>& other); @@ -62,6 +64,12 @@ TNodeWrapperCommonOps<TThis>::TNodeWrapperCommonOps( , PathFromCheckNode_(pathFromCheckNode) {} template <typename TThis> +TNodeWrapperCommonOps<TThis>::TNodeWrapperCommonOps(const TNodeWrapperCommonOps<TThis>& other) + : Context_(other.Context_) + , Node_(other.Node_) + , PathFromCheckNode_(other.PathFromCheckNode_) {} + +template <typename TThis> TNodeWrapperCommonOps<TThis>& TNodeWrapperCommonOps<TThis>::operator=(const TNodeWrapperCommonOps<TThis>& other) { Context_ = other.Context_; Node_ = other.Node_; @@ -121,6 +129,7 @@ public: TStringNodeWrapper String(); TBoolNodeWrapper Bool(); TEnumNodeWrapper Enum(); + TString Scalar(); TMaybe<ENodeType> ValidatorType(); diff --git a/ydb/library/yaml_config/validator/ya.make b/ydb/library/yaml_config/validator/ya.make index d2ce3c08ce3..ce37734c63e 100644 --- a/ydb/library/yaml_config/validator/ya.make +++ b/ydb/library/yaml_config/validator/ya.make @@ -7,6 +7,8 @@ SRCS( validator.cpp validator_checks.h validator_checks.cpp + configurators.h + configurators.cpp ) PEERDIR( diff --git a/ydb/library/yaml_config/ya.make b/ydb/library/yaml_config/ya.make index 637f71bbd9c..e8133b9dcad 100644 --- a/ydb/library/yaml_config/ya.make +++ b/ydb/library/yaml_config/ya.make @@ -28,6 +28,7 @@ END() RECURSE( public validator + static_validator ) RECURSE_FOR_TESTS( |