diff --git a/ydb/core/base/kmeans_clusters.cpp b/ydb/core/base/kmeans_clusters.cpp index 65fb9874d76c..32777d2ee5a0 100644 --- a/ydb/core/base/kmeans_clusters.cpp +++ b/ydb/core/base/kmeans_clusters.cpp @@ -453,6 +453,11 @@ std::unique_ptr CreateClusters(const Ydb::Table::VectorIndexSettings& bool ValidateSettings(const Ydb::Table::KMeansTreeSettings& settings, TString& error) { error = ""; + if (auto unknownCount = settings.GetReflection()->GetUnknownFields(settings).field_count(); unknownCount > 0) { + error = TStringBuilder() << "vector index settings contain " << unknownCount << " unsupported parameter(s)"; + return false; + } + if (!settings.has_settings()) { error = TStringBuilder() << "vector index settings should be set"; return false; @@ -497,7 +502,10 @@ bool ValidateSettings(const Ydb::Table::KMeansTreeSettings& settings, TString& e } bool ValidateSettings(const Ydb::Table::VectorIndexSettings& settings, TString& error) { - error = ""; + if (auto unknownCount = settings.GetReflection()->GetUnknownFields(settings).field_count(); unknownCount > 0) { + error = TStringBuilder() << "vector index settings contain " << unknownCount << " unsupported parameter(s)"; + return false; + } if (!settings.has_metric() || settings.metric() == Ydb::Table::VectorIndexSettings::METRIC_UNSPECIFIED) { error = TStringBuilder() << "either distance or similarity should be set"; diff --git a/ydb/core/base/ut/kmeans_ut.cpp b/ydb/core/base/ut/kmeans_ut.cpp new file mode 100644 index 000000000000..5e780c05e401 --- /dev/null +++ b/ydb/core/base/ut/kmeans_ut.cpp @@ -0,0 +1,90 @@ +#include "kmeans_clusters.h" + +#include + +#include +#include + +namespace NKikimr::NKMeans { + +Y_UNIT_TEST_SUITE(NKMeans) { + + Y_UNIT_TEST(ValidateSettings) { + Ydb::Table::KMeansTreeSettings settings; + TString error; + + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_VALUES_EQUAL(error, "vector index settings should be set"); + + auto& vectorIndex = *settings.mutable_settings(); + + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_VALUES_EQUAL(error, "either distance or similarity should be set"); + + vectorIndex.set_metric((::Ydb::Table::VectorIndexSettings_Metric)UINT32_MAX); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid metric"); + + vectorIndex.set_metric(Ydb::Table::VectorIndexSettings::DISTANCE_COSINE); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_VALUES_EQUAL(error, "vector_type should be set"); + + vectorIndex.set_vector_type((::Ydb::Table::VectorIndexSettings_VectorType)UINT32_MAX); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid vector_type"); + + vectorIndex.set_vector_type(Ydb::Table::VectorIndexSettings::VECTOR_TYPE_BIT); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "vector_dimension should be set"); + + vectorIndex.set_vector_dimension(UINT32_MAX); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid vector_dimension"); + + vectorIndex.set_vector_dimension(16384); + vectorIndex.GetReflection()->MutableUnknownFields(&vectorIndex)->AddVarint(10000, 100000); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "vector index settings contain 1 unsupported parameter(s)"); + + vectorIndex.GetReflection()->MutableUnknownFields(&vectorIndex)->DeleteByNumber(10000); + settings.GetReflection()->MutableUnknownFields(&settings)->AddVarint(10000, 100000); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "vector index settings contain 1 unsupported parameter(s)"); + + settings.GetReflection()->MutableUnknownFields(&settings)->DeleteByNumber(10000); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "levels should be set"); + + settings.set_levels(UINT32_MAX); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid levels"); + + settings.set_levels(16); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "clusters should be set"); + + settings.set_clusters(UINT32_MAX); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid clusters"); + + settings.set_clusters(2048); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid clusters^levels"); + + settings.set_clusters(4); + settings.set_levels(16); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid clusters^levels"); + + settings.set_clusters(1024); + settings.set_levels(3); + UNIT_ASSERT(!ValidateSettings(settings, error)); + UNIT_ASSERT_STRING_CONTAINS(error, "Invalid vector_dimension*clusters"); + + settings.set_clusters(50); + settings.set_levels(3); + UNIT_ASSERT(ValidateSettings(settings, error)); + } +} + +} diff --git a/ydb/core/base/ut/ya.make b/ydb/core/base/ut/ya.make index 82b340fde09c..e1da0f1fe250 100644 --- a/ydb/core/base/ut/ya.make +++ b/ydb/core/base/ut/ya.make @@ -6,11 +6,15 @@ SIZE(MEDIUM) PEERDIR( library/cpp/getopt library/cpp/svnversion + ydb/core/scheme + yql/essentials/public/udf/service/stub + yql/essentials/sql/pg_dummy ) SRCS( path_ut.cpp blobstorage_grouptype_ut.cpp + kmeans_ut.cpp localdb_ut.cpp logoblob_ut.cpp memory_stats_ut.cpp