test_web.cpp 68.8 KB
Newer Older
1
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
B
BossZou 已提交
2
//
3 4
// Licensed 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
B
BossZou 已提交
5
//
6 7 8 9 10
// 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.
B
BossZou 已提交
11 12

#include <unistd.h>
13

14 15
#include <random>
#include <thread>
B
BossZou 已提交
16

B
BossZou 已提交
17 18
#include <fiu-control.h>
#include <fiu-local.h>
19
#include <gtest/gtest.h>
Y
yukun 已提交
20
#include <boost/filesystem.hpp>
B
BossZou 已提交
21
#include <oatpp/core/macro/component.hpp>
22
#include <oatpp/network/client/SimpleTCPConnectionProvider.hpp>
B
BossZou 已提交
23
#include <oatpp/web/client/ApiClient.hpp>
24
#include <oatpp/web/client/HttpRequestExecutor.hpp>
B
BossZou 已提交
25

26
#include "config/Config.h"
27 28 29
#include "scheduler/ResourceFactory.h"
#include "scheduler/SchedInst.h"
#include "server/DBWrapper.h"
B
BossZou 已提交
30 31
#include "server/web_impl/Types.h"
#include "server/web_impl/WebServer.h"
B
BossZou 已提交
32
#include "server/web_impl/dto/CollectionDto.hpp"
33 34 35
#include "server/web_impl/dto/StatusDto.hpp"
#include "server/web_impl/dto/VectorDto.hpp"
#include "server/web_impl/handler/WebRequestHandler.h"
B
BossZou 已提交
36
#include "src/version.h"
B
BossZou 已提交
37
#include "utils/CommonUtil.h"
38
#include "utils/StringHelpFunctions.h"
B
BossZou 已提交
39

B
BossZou 已提交
40
static const char* COLLECTION_NAME = "test_milvus_web_collection";
B
BossZou 已提交
41 42 43 44 45 46 47

using OStatus = oatpp::web::protocol::http::Status;
using OString = milvus::server::web::OString;
using OQueryParams = milvus::server::web::OQueryParams;
using OChunkedBuffer = oatpp::data::stream::ChunkedBuffer;
using OOutputStream = oatpp::data::stream::BufferOutputStream;
using OFloat32 = milvus::server::web::OFloat32;
48
using OInt64 = milvus::server::web::OInt64;
Y
yukun 已提交
49
template <class T>
B
BossZou 已提交
50 51 52 53 54 55
using OList = milvus::server::web::OList<T>;

using StatusCode = milvus::server::web::StatusCode;

namespace {

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
nlohmann::json
RandomRawRecordJson(int64_t dim) {
    nlohmann::json json;

    std::default_random_engine e;
    std::uniform_real_distribution<float> u(0, 1);
    for (size_t i = 0; i < dim; i++) {
        json.push_back(u(e));
    }

    return json;
}

nlohmann::json
RandomRecordsJson(int64_t dim, int64_t num) {
    nlohmann::json json;
    for (size_t i = 0; i < num; i++) {
        json.push_back(RandomRawRecordJson(dim));
    }

    return json;
}

nlohmann::json
RandomRawBinRecordJson(int64_t dim) {
    nlohmann::json json;

    std::default_random_engine e;
    std::uniform_real_distribution<float> u(0, 255);
    for (size_t i = 0; i < dim / 8; i++) {
        json.push_back(static_cast<uint8_t>(u(e)));
    }

    return json;
}

nlohmann::json
RandomBinRecordsJson(int64_t dim, int64_t num) {
    nlohmann::json json;
    for (size_t i = 0; i < num; i++) {
        json.push_back(RandomRawBinRecordJson(dim));
    }

    return json;
}

102 103 104 105 106 107 108 109 110 111 112
nlohmann::json
RandomAttrRecordsJson(int64_t row_num) {
    nlohmann::json json;
    std::default_random_engine e;
    std::uniform_int_distribution<unsigned> u(0, 1000);
    for (size_t i = 0; i < row_num; i++) {
        json.push_back(u(e));
    }
    return json;
}

B
BossZou 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
std::string
RandomName() {
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::default_random_engine e(seed);
    std::uniform_int_distribution<unsigned> u(0, 1000000);

    size_t name_len = u(e) % 16 + 3;

    char* name = new char[name_len + 1];
    name[name_len] = '\0';

    for (size_t i = 0; i < name_len; i++) {
        unsigned random_i = u(e);
        char remainder = static_cast<char>(random_i % 26);
        name[i] = (random_i % 2 == 0) ? 'A' + remainder : 'a' + remainder;
    }

    std::string random_name(name);

    delete[] name;

    return random_name;
}

Y
yukun 已提交
137
}  // namespace
B
BossZou 已提交
138 139 140 141

///////////////////////////////////////////////////////////////////////////////////////

namespace {
142 143 144
static const char* CONTROLLER_TEST_VALID_CONFIG_STR =
    "# Default values are used when you make no changes to the following parameters.\n"
    "\n"
W
Wang XiangYu 已提交
145
    "version: 0.5\n"
146
    "\n"
W
Wang XiangYu 已提交
147 148 149
    "cluster:\n"
    "  enable: false\n"
    "  role: rw\n"
150
    "\n"
W
Wang XiangYu 已提交
151 152 153
    "general:\n"
    "  timezone: UTC+8\n"
    "  meta_uri: sqlite://:@:/\n"
154
    "\n"
W
Wang XiangYu 已提交
155 156 157 158 159
    "network:\n"
    "  bind.address: 0.0.0.0\n"
    "  bind.port: 19530\n"
    "  http.enable: true\n"
    "  http.port: 19121\n"
160
    "\n"
W
Wang XiangYu 已提交
161 162 163
    "storage:\n"
    "  path: /tmp/milvus\n"
    "  auto_flush_interval: 1\n"
164
    "\n"
W
Wang XiangYu 已提交
165 166 167 168 169
    "wal:\n"
    "  enable: true\n"
    "  recovery_error_ignore: false\n"
    "  buffer_size: 256MB\n"
    "  path: /tmp/milvus/wal\n"
170
    "\n"
W
Wang XiangYu 已提交
171 172 173 174
    "cache:\n"
    "  cache_size: 4GB\n"
    "  insert_buffer_size: 1GB\n"
    "  preload_collection:\n"
175
    "\n"
W
Wang XiangYu 已提交
176
    "gpu:\n"
177
    "  enable: true\n"
W
Wang XiangYu 已提交
178 179 180
    "  cache_size: 1GB\n"
    "  gpu_search_threshold: 1000\n"
    "  search_devices:\n"
181
    "    - gpu0\n"
W
Wang XiangYu 已提交
182
    "  build_index_devices:\n"
183
    "    - gpu0\n"
184
    "\n"
W
Wang XiangYu 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197
    "logs:\n"
    "  level: debug\n"
    "  trace.enable: true\n"
    "  path: /tmp/milvus/logs\n"
    "  max_log_file_size: 1024MB\n"
    "  log_rotate_num: 0\n"
    "\n"
    "metric:\n"
    "  enable: false\n"
    "  address: 127.0.0.1\n"
    "  port: 9091\n"
    "\n";

198
}  // namespace
199

G
groot 已提交
200
static const char* CONTROLLER_TEST_COLLECTION_NAME = "controller_unit_test";
201
static const char* CONTROLLER_TEST_CONFIG_DIR = "/tmp/milvus_web_controller_test/";
W
Wang XiangYu 已提交
202
static const char* CONTROLLER_TEST_CONFIG_WAL_DIR = "/tmp/milvus_web_controller_test/wal";
203
static const char* CONTROLLER_TEST_CONFIG_FILE = "config.yaml";
B
BossZou 已提交
204 205 206 207

class TestClient : public oatpp::web::client::ApiClient {
 public:
#include OATPP_CODEGEN_BEGIN(ApiClient)
Y
yukun 已提交
208
    API_CLIENT_INIT(TestClient)
B
BossZou 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

    API_CALL("GET", "/", root)

    API_CALL("GET", "/state", getState)

    API_CALL("GET", "/devices", getDevices)

    API_CALL("GET", "/config/advanced", getAdvanced)

    API_CALL("OPTIONS", "/config/advanced", optionsAdvanced)

    API_CALL("PUT", "/config/advanced", setAdvanced,
             BODY_DTO(milvus::server::web::AdvancedConfigDto::ObjectWrapper, body))

#ifdef MILVUS_GPU_VERSION
224

B
BossZou 已提交
225 226 227 228 229 230
    API_CALL("OPTIONS", "config/gpu_resources", optionsGpuConfig)

    API_CALL("GET", "/config/gpu_resources", getGPUConfig)

    API_CALL("PUT", "/config/gpu_resources", setGPUConfig,
             BODY_DTO(milvus::server::web::GPUConfigDto::ObjectWrapper, body))
231

B
BossZou 已提交
232 233
#endif

B
BossZou 已提交
234
    API_CALL("OPTIONS", "/collections", optionsCollections)
B
BossZou 已提交
235

Y
yukun 已提交
236 237
    API_CALL("POST", "/collections", createCollection,
             BODY_DTO(milvus::server::web::CollectionRequestDto::ObjectWrapper, body))
B
BossZou 已提交
238

B
BossZou 已提交
239
    API_CALL("GET", "/collections", showCollections, QUERY(String, offset), QUERY(String, page_size))
B
BossZou 已提交
240

B
BossZou 已提交
241
    API_CALL("OPTIONS", "/collections/{collection_name}", optionsCollection,
242
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
243

Y
yukun 已提交
244 245
    API_CALL("GET", "/collections/{collection_name}", getCollection, PATH(String, collection_name, "collection_name"),
             QUERY(String, info))
B
BossZou 已提交
246

Y
yukun 已提交
247 248
    API_CALL("DELETE", "/collections/{collection_name}", dropCollection,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
249

250 251
    API_CALL("OPTIONS", "/collections/{collection_name}/indexes", optionsIndexes,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
252

253 254
    API_CALL("POST", "/collections/{collection_name}/indexes", createIndex,
             PATH(String, collection_name, "collection_name"), BODY_STRING(OString, body))
B
BossZou 已提交
255

256 257
    API_CALL("GET", "/collections/{collection_name}/indexes", getIndex,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
258

259 260
    API_CALL("DELETE", "/collections/{collection_name}/indexes", dropIndex,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
261

262 263
    API_CALL("OPTIONS", "/collections/{collection_name}/partitions", optionsPartitions,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
264

265 266
    API_CALL("POST", "/collections/{collection_name}/partitions", createPartition,
             PATH(String, collection_name, "collection_name"),
267
             BODY_DTO(milvus::server::web::PartitionRequestDto::ObjectWrapper, body))
B
BossZou 已提交
268

269
    API_CALL("GET", "/collections/{collection_name}/partitions", showPartitions,
Y
yukun 已提交
270 271
             PATH(String, collection_name, "collection_name"), QUERY(String, offset), QUERY(String, page_size),
             BODY_STRING(String, body))
B
BossZou 已提交
272

273 274
    API_CALL("DELETE", "/collections/{collection_name}/partitions", dropPartition,
             PATH(String, collection_name, "collection_name"), BODY_STRING(String, body))
275

276
    API_CALL("GET", "/collections/{collection_name}/segments", showSegments,
Y
yukun 已提交
277 278
             PATH(String, collection_name, "collection_name"), QUERY(String, offset), QUERY(String, page_size),
             QUERY(String, partition_tag))
B
BossZou 已提交
279

280 281
    API_CALL("GET", "/collections/{collection_name}/segments/{segment_name}/{info}", getSegmentInfo,
             PATH(String, collection_name, "collection_name"), PATH(String, segment_name, "segment_name"),
282
             PATH(String, info, "info"), QUERY(String, offset), QUERY(String, page_size))
B
BossZou 已提交
283

284 285
    API_CALL("OPTIONS", "/collections/{collection_name}/vectors", optionsVectors,
             PATH(String, collection_name, "collection_name"))
B
BossZou 已提交
286

287
    API_CALL("GET", "/collections/{collection_name}/vectors", getVectors,
288
             PATH(String, collection_name, "collection_name"), QUERY(String, ids))
B
BossZou 已提交
289

Y
yukun 已提交
290 291
    API_CALL("POST", "/collections/{collection_name}/vectors", insert, PATH(String, collection_name, "collection_name"),
             BODY_STRING(String, body))
292

293 294
    API_CALL("PUT", "/collections/{collection_name}/vectors", vectorsOp,
             PATH(String, collection_name, "collection_name"), BODY_STRING(String, body))
B
BossZou 已提交
295

296
    API_CALL("GET", "/system/{msg}", cmd, PATH(String, cmd_str, "msg"), QUERY(String, action), QUERY(String, target))
B
BossZou 已提交
297

298
    API_CALL("PUT", "/system/{op}", op, PATH(String, cmd_str, "op"), BODY_STRING(String, body))
299

300 301
    API_CALL("POST", "/hybrid_collections", createHybridCollection, BODY_STRING(String, body_str))

Y
yukun 已提交
302 303
    API_CALL("POST", "/hybrid_collections/{collection_name}/entities", InsertEntity, PATH(String, collection_name),
             BODY_STRING(String, body))
304

B
BossZou 已提交
305 306 307
#include OATPP_CODEGEN_END(ApiClient)
};

308 309 310 311 312
using TestClientP = std::shared_ptr<TestClient>;
using TestConnP = std::shared_ptr<oatpp::web::client::RequestExecutor::ConnectionHandle>;

class WebControllerTest : public ::testing::Test {
 public:
B
BossZou 已提交
313 314
    static void
    SetUpTestCase() {
315
        mkdir(CONTROLLER_TEST_CONFIG_DIR, S_IRWXU);
316
        // Load basic config
317 318 319
        std::string config_path = std::string(CONTROLLER_TEST_CONFIG_DIR).append(CONTROLLER_TEST_CONFIG_FILE);
        std::fstream fs(config_path.c_str(), std::ios_base::out);
        fs << CONTROLLER_TEST_VALID_CONFIG_STR;
320
        fs.flush();
321 322 323 324 325
        fs.close();

        milvus::server::Config& config = milvus::server::Config::GetInstance();
        config.LoadConfigFile(config_path);

B
BossZou 已提交
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
        auto res_mgr = milvus::scheduler::ResMgrInst::GetInstance();
        res_mgr->Clear();
        res_mgr->Add(milvus::scheduler::ResourceFactory::Create("disk", "DISK", 0, false));
        res_mgr->Add(milvus::scheduler::ResourceFactory::Create("cpu", "CPU", 0));
        res_mgr->Add(milvus::scheduler::ResourceFactory::Create("gtx1660", "GPU", 0));

        auto default_conn = milvus::scheduler::Connection("IO", 500.0);
        auto PCIE = milvus::scheduler::Connection("IO", 11000.0);
        res_mgr->Connect("disk", "cpu", default_conn);
        res_mgr->Connect("cpu", "gtx1660", PCIE);
        res_mgr->Start();
        milvus::scheduler::SchedInst::GetInstance()->Start();
        milvus::scheduler::JobMgrInst::GetInstance()->Start();

        milvus::engine::DBOptions opt;

W
Wang XiangYu 已提交
342
        milvus::server::Config::GetInstance().SetGeneralConfigMetaURI("sqlite://:@:/");
343
        boost::filesystem::remove_all(CONTROLLER_TEST_CONFIG_DIR);
W
Wang XiangYu 已提交
344 345
        milvus::server::Config::GetInstance().SetStorageConfigPath(CONTROLLER_TEST_CONFIG_DIR);
        milvus::server::Config::GetInstance().SetWalConfigWalPath(CONTROLLER_TEST_CONFIG_WAL_DIR);
B
BossZou 已提交
346 347 348

        milvus::server::DBWrapper::GetInstance().StartService();

W
Wang XiangYu 已提交
349
        milvus::server::Config::GetInstance().SetNetworkConfigHTTPPort("29999");
B
BossZou 已提交
350 351 352

        milvus::server::web::WebServer::GetInstance().Start();

353
        sleep(3);
B
BossZou 已提交
354 355 356 357 358 359 360 361 362 363
    }

    static void
    TearDownTestCase() {
        milvus::server::web::WebServer::GetInstance().Stop();

        milvus::server::DBWrapper::GetInstance().StopService();
        milvus::scheduler::JobMgrInst::GetInstance()->Stop();
        milvus::scheduler::ResMgrInst::GetInstance()->Stop();
        milvus::scheduler::SchedInst::GetInstance()->Stop();
364
        boost::filesystem::remove_all(CONTROLLER_TEST_CONFIG_DIR);
B
BossZou 已提交
365 366 367
    }

    void
368 369 370 371 372
    SetUp() override {
        std::string config_path = std::string(CONTROLLER_TEST_CONFIG_DIR).append(CONTROLLER_TEST_CONFIG_FILE);
        std::fstream fs(config_path.c_str(), std::ios_base::out);
        fs << CONTROLLER_TEST_VALID_CONFIG_STR;
        fs.close();
B
BossZou 已提交
373

374 375
        milvus::server::Config& config = milvus::server::Config::GetInstance();
        config.LoadConfigFile(std::string(CONTROLLER_TEST_CONFIG_DIR) + CONTROLLER_TEST_CONFIG_FILE);
376

377 378 379
        OATPP_COMPONENT(std::shared_ptr<oatpp::network::ClientConnectionProvider>, clientConnectionProvider);
        OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper);
        object_mapper = objectMapper;
380

381 382
        auto requestExecutor = oatpp::web::client::HttpRequestExecutor::createShared(clientConnectionProvider);
        client_ptr = TestClient::createShared(requestExecutor, objectMapper);
383

384
        conncetion_ptr = client_ptr->getConnection();
385 386
    }

387
    void
Y
yukun 已提交
388
    TearDown() override{};
389

390 391 392 393 394
 protected:
    std::shared_ptr<oatpp::data::mapping::ObjectMapper> object_mapper;
    TestConnP conncetion_ptr;
    TestClientP client_ptr;
};
395

396 397
namespace {
void
B
BossZou 已提交
398
GenCollection(const TestClientP& client_ptr, const TestConnP& connection_ptr, const OString& collection_name,
Y
yukun 已提交
399
              int64_t dim, int64_t index_size, const OString& metric) {
B
BossZou 已提交
400
    auto response = client_ptr->getCollection(collection_name, "", connection_ptr);
401 402 403
    if (OStatus::CODE_200.code == response->getStatusCode()) {
        return;
    }
B
BossZou 已提交
404
    auto collection_dto = milvus::server::web::CollectionRequestDto::createShared();
405 406 407 408
    collection_dto->collection_name = collection_name;
    collection_dto->dimension = dim;
    collection_dto->index_file_size = index_size;
    collection_dto->metric_type = metric;
B
BossZou 已提交
409
    client_ptr->createCollection(collection_dto, connection_ptr);
410
}
411

412
milvus::Status
B
BossZou 已提交
413
FlushCollection(const TestClientP& client_ptr, const TestConnP& connection_ptr, const OString& collection_name) {
414 415 416 417 418 419
    nlohmann::json flush_json;
    flush_json["flush"]["collection_names"] = {collection_name->std_str()};
    auto response = client_ptr->op("task", flush_json.dump().c_str(), connection_ptr);
    if (OStatus::CODE_200.code != response->getStatusCode()) {
        return milvus::Status(milvus::SERVER_UNEXPECTED_ERROR, response->readBodyToString()->std_str());
    }
420

421 422
    return milvus::Status::OK();
}
423

424
milvus::Status
Y
yukun 已提交
425 426
InsertData(const TestClientP& client_ptr, const TestConnP& connection_ptr, const OString& collection_name, int64_t dim,
           int64_t count, std::string tag = "", bool bin = false) {
427
    nlohmann::json insert_json;
428

429 430 431 432
    if (bin)
        insert_json["vectors"] = RandomBinRecordsJson(dim, count);
    else
        insert_json["vectors"] = RandomRecordsJson(dim, count);
433

434 435
    if (!tag.empty()) {
        insert_json["partition_tag"] = tag;
436 437
    }

438 439 440
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), connection_ptr);
    if (OStatus::CODE_201.code != response->getStatusCode()) {
        return milvus::Status(milvus::SERVER_UNEXPECTED_ERROR, response->readBodyToString()->c_str());
441 442
    }

B
BossZou 已提交
443
    return FlushCollection(client_ptr, connection_ptr, collection_name);
444
}
445

446
milvus::Status
Y
yukun 已提交
447 448
InsertData(const TestClientP& client_ptr, const TestConnP& connection_ptr, const OString& collection_name, int64_t dim,
           int64_t count, const std::vector<std::string>& ids, std::string tag = "", bool bin = false) {
449
    nlohmann::json insert_json;
B
BossZou 已提交
450

451 452 453 454
    if (bin)
        insert_json["vectors"] = RandomBinRecordsJson(dim, count);
    else
        insert_json["vectors"] = RandomRecordsJson(dim, count);
B
BossZou 已提交
455

456 457
    if (!ids.empty()) {
        insert_json["ids"] = ids;
B
BossZou 已提交
458 459
    }

460 461 462
    if (!tag.empty()) {
        insert_json["partition_tag"] = tag;
    }
B
BossZou 已提交
463

464 465 466 467
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), connection_ptr);
    if (OStatus::CODE_201.code != response->getStatusCode()) {
        return milvus::Status(milvus::SERVER_UNEXPECTED_ERROR, response->readBodyToString()->c_str());
    }
B
BossZou 已提交
468

B
BossZou 已提交
469
    return FlushCollection(client_ptr, connection_ptr, collection_name);
470
}
471

472
milvus::Status
Y
yukun 已提交
473 474
GenPartition(const TestClientP& client_ptr, const TestConnP& connection_ptr, const OString& collection_name,
             const OString& tag) {
475 476 477 478 479
    auto par_param = milvus::server::web::PartitionRequestDto::createShared();
    par_param->partition_tag = tag;
    auto response = client_ptr->createPartition(collection_name, par_param);
    if (OStatus::CODE_201.code != response->getStatusCode()) {
        return milvus::Status(milvus::SERVER_UNEXPECTED_ERROR, response->readBodyToString()->c_str());
B
BossZou 已提交
480 481
    }

482 483
    return milvus::Status::OK();
}
484
}  // namespace
485

B
BossZou 已提交
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
TEST_F(WebControllerTest, OPTIONS) {
    auto response = client_ptr->root(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    response = client_ptr->getState(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    response = client_ptr->optionsAdvanced(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

#ifdef MILVUS_GPU_VERSION
    response = client_ptr->optionsGpuConfig(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
#endif

    response = client_ptr->optionsIndexes("test", conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

504
    response = client_ptr->optionsPartitions("collection_name", conncetion_ptr);
B
BossZou 已提交
505 506
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

B
BossZou 已提交
507
    response = client_ptr->optionsCollection("collection", conncetion_ptr);
B
BossZou 已提交
508 509
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

B
BossZou 已提交
510
    response = client_ptr->optionsCollections(conncetion_ptr);
B
BossZou 已提交
511 512
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

513
    response = client_ptr->optionsVectors("collection", conncetion_ptr);
B
BossZou 已提交
514 515 516
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
}

G
groot 已提交
517
TEST_F(WebControllerTest, CREATE_COLLECTION) {
B
BossZou 已提交
518 519
    auto collection_dto = milvus::server::web::CollectionRequestDto::createShared();
    auto response = client_ptr->createCollection(collection_dto, conncetion_ptr);
B
BossZou 已提交
520
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
521 522
    auto error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::BODY_FIELD_LOSS, error_dto->code) << error_dto->message->std_str();
B
BossZou 已提交
523

524
    OString collection_name = "web_test_create_collection" + OString(RandomName().c_str());
B
BossZou 已提交
525

526
    collection_dto->collection_name = collection_name;
B
BossZou 已提交
527
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
B
BossZou 已提交
528
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
529 530
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::BODY_FIELD_LOSS, error_dto->code) << error_dto->message->std_str();
B
BossZou 已提交
531

532 533 534
    collection_dto->dimension = 128;
    collection_dto->index_file_size = 10;
    collection_dto->metric_type = "L2";
B
BossZou 已提交
535

B
BossZou 已提交
536
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
B
BossZou 已提交
537
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
538 539
    auto result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::SUCCESS, result_dto->code->getValue()) << result_dto->message->std_str();
B
BossZou 已提交
540

541 542
    // invalid collection name
    collection_dto->collection_name = "9090&*&()";
B
BossZou 已提交
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

    // invalid dimension
    collection_dto->collection_name = collection_name;
    collection_dto->dimension = 100000;
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

    // invalid index file size
    collection_dto->dimension = 128;
    collection_dto->index_file_size = -1;
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

    // invalid metric type
    collection_dto->index_file_size = 1024;
    collection_dto->metric_type = "L0";
    response = client_ptr->createCollection(collection_dto, conncetion_ptr);
B
BossZou 已提交
562 563 564
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
}

565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
TEST_F(WebControllerTest, HYBRID_TEST) {
    nlohmann::json create_json;
    create_json["collection_name"] = "test_hybrid";
    nlohmann::json field_json_0, field_json_1;
    field_json_0["field_name"] = "field_0";
    field_json_0["field_type"] = "int64";
    field_json_0["extra_params"] = "";

    field_json_1["field_name"] = "field_1";
    field_json_1["field_type"] = "vector";
    nlohmann::json extra_params;
    extra_params["dimension"] = 128;
    field_json_1["extra_params"] = extra_params;

    create_json["fields"].push_back(field_json_0);
    create_json["fields"].push_back(field_json_1);

    auto response = client_ptr->createHybridCollection(create_json.dump().c_str());
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
    auto result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::SUCCESS, result_dto->code->getValue()) << result_dto->message->std_str();

    int64_t dimension = 128;
    int64_t row_num = 1000;
    nlohmann::json insert_json;
    insert_json["partition_tag"] = "";
    nlohmann::json entity_0, entity_1;
    entity_0["field_name"] = "field_0";
    entity_0["field_value"] = RandomAttrRecordsJson(row_num);
    entity_1["field_name"] = "field_1";
    entity_1["field_value"] = RandomRecordsJson(dimension, row_num);

    insert_json["entity"].push_back(entity_0);
    insert_json["entity"].push_back(entity_1);
    insert_json["row_num"] = row_num;

    OString collection_name = "test_hybrid";
    response = client_ptr->InsertEntity(collection_name, insert_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
    auto vector_dto = response->readBodyToDto<milvus::server::web::VectorIdsDto>(object_mapper.get());
    ASSERT_EQ(row_num, vector_dto->ids->count());

B
BossZou 已提交
607
    auto status = FlushCollection(client_ptr, conncetion_ptr, collection_name);
608 609 610 611 612
    ASSERT_TRUE(status.ok()) << status.message();

    // TODO(yukun): when hybrid operation is added to wal, the sleep() can be deleted
    sleep(2);

Y
yukun 已提交
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
    //    int64_t nq = 10;
    //    int64_t topk = 100;
    //    nlohmann::json query_json, bool_json, term_json, range_json, vector_json;
    //    term_json["term"]["field_name"] = "field_0";
    //    term_json["term"]["values"] = RandomAttrRecordsJson(nq);
    //    bool_json["must"].push_back(term_json);
    //
    //    range_json["range"]["field_name"] = "field_0";
    //    nlohmann::json comp_json;
    //    comp_json["gte"] = "0";
    //    comp_json["lte"] = "100000";
    //    range_json["range"]["values"] = comp_json;
    //    bool_json["must"].push_back(range_json);
    //
    //    vector_json["vector"]["field_name"] = "field_1";
    //    vector_json["vector"]["topk"] = topk;
    //    vector_json["vector"]["nq"] = nq;
    //    vector_json["vector"]["values"] = RandomRecordsJson(128, nq);
    //    bool_json["must"].push_back(vector_json);
    //
    //    query_json["query"]["bool"] = bool_json;
    //
    //    response = client_ptr->vectorsOp(collection_name, query_json.dump().c_str(), conncetion_ptr);
    //    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
    //
    //    auto result_json = nlohmann::json::parse(response->readBodyToString()->std_str());
    //    ASSERT_TRUE(result_json.contains("num"));
    //    ASSERT_TRUE(result_json["num"].is_number());
    //    ASSERT_EQ(nq, result_json["num"].get<int64_t>());
    //
    //    ASSERT_TRUE(result_json.contains("result"));
    //    ASSERT_TRUE(result_json["result"].is_array());
645

646
    // TODO: kunyu
Y
yukun 已提交
647 648 649
    //    auto result0_json = result_json["result"][0];
    //    ASSERT_TRUE(result0_json.is_array());
    //    ASSERT_EQ(topk, result0_json.size());
650 651
}

G
groot 已提交
652
TEST_F(WebControllerTest, GET_COLLECTION_META) {
653
    OString collection_name = "web_test_create_collection" + OString(RandomName().c_str());
B
BossZou 已提交
654
    GenCollection(client_ptr, conncetion_ptr, collection_name, 10, 10, "L2");
B
BossZou 已提交
655 656 657

    OQueryParams params;

B
BossZou 已提交
658
    auto response = client_ptr->getCollection(collection_name, "", conncetion_ptr);
B
BossZou 已提交
659
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
B
BossZou 已提交
660
    auto result_dto = response->readBodyToDto<milvus::server::web::CollectionFieldsDto>(object_mapper.get());
661
    ASSERT_EQ(collection_name->std_str(), result_dto->collection_name->std_str());
662 663 664 665
    ASSERT_EQ(10, result_dto->dimension);
    ASSERT_EQ("L2", result_dto->metric_type->std_str());
    ASSERT_EQ(10, result_dto->index_file_size->getValue());
    ASSERT_EQ("FLAT", result_dto->index->std_str());
B
BossZou 已提交
666

667 668
    // invalid collection name
    collection_name = "57474dgdfhdfhdh  dgd";
B
BossZou 已提交
669
    response = client_ptr->getCollection(collection_name, "", conncetion_ptr);
B
BossZou 已提交
670 671
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
    auto status_sto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
672
    ASSERT_EQ(milvus::server::web::StatusCode::ILLEGAL_COLLECTION_NAME, status_sto->code->getValue());
B
BossZou 已提交
673

674
    collection_name = "test_collection_not_found_000000000111010101002020203020aaaaa3030435";
B
BossZou 已提交
675
    response = client_ptr->getCollection(collection_name, "", conncetion_ptr);
B
BossZou 已提交
676 677 678
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
}

G
groot 已提交
679
TEST_F(WebControllerTest, GET_COLLECTION_STAT) {
680
    OString collection_name = "web_test_get_collection_stat" + OString(RandomName().c_str());
B
BossZou 已提交
681
    GenCollection(client_ptr, conncetion_ptr, collection_name, 128, 5, "L2");
682 683

    for (size_t i = 0; i < 5; i++) {
684
        InsertData(client_ptr, conncetion_ptr, collection_name, 128, 1000);
685 686
    }

B
BossZou 已提交
687
    auto response = client_ptr->getCollection(collection_name, "stat", conncetion_ptr);
688 689
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

690 691 692 693
    std::string json_str = response->readBodyToString()->c_str();
    auto result_json = nlohmann::json::parse(json_str);
    ASSERT_TRUE(result_json.contains("row_count"));
    ASSERT_EQ(5 * 1000, result_json["row_count"].get<uint64_t>());
694

695 696 697
    ASSERT_TRUE(result_json.contains("partitions"));

    auto partitions_stat_json = result_json["partitions"];
698 699 700
    ASSERT_TRUE(partitions_stat_json.is_array());

    auto partition0_json = partitions_stat_json[0];
701 702 703 704 705 706 707 708 709
    ASSERT_TRUE(partition0_json.contains("segments"));
    ASSERT_TRUE(partition0_json.contains("row_count"));
    ASSERT_TRUE(partition0_json.contains("tag"));

    auto seg0_stat = partition0_json["segments"][0];
    ASSERT_TRUE(seg0_stat.contains("name"));
    ASSERT_TRUE(seg0_stat.contains("index_name"));
    ASSERT_TRUE(seg0_stat.contains("row_count"));
    ASSERT_TRUE(seg0_stat.contains("data_size"));
710 711
}

G
groot 已提交
712
TEST_F(WebControllerTest, SHOW_COLLECTIONS) {
713
    // test query collection limit 1
B
BossZou 已提交
714
    auto response = client_ptr->showCollections("1", "1", conncetion_ptr);
B
BossZou 已提交
715
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
B
BossZou 已提交
716
    auto result_dto = response->readBodyToDto<milvus::server::web::CollectionListFieldsDto>(object_mapper.get());
717
    ASSERT_GE(result_dto->count->getValue(), 0);
B
BossZou 已提交
718

719
    // test query collection empty
B
BossZou 已提交
720
    response = client_ptr->showCollections("0", "0", conncetion_ptr);
B
BossZou 已提交
721 722
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

B
BossZou 已提交
723
    response = client_ptr->showCollections("-1", "0", conncetion_ptr);
B
BossZou 已提交
724 725
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

B
BossZou 已提交
726
    response = client_ptr->showCollections("0", "-10", conncetion_ptr);
B
BossZou 已提交
727 728 729
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

    // test wrong param
B
BossZou 已提交
730
    response = client_ptr->showCollections("0.1", "1", conncetion_ptr);
B
BossZou 已提交
731 732
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

B
BossZou 已提交
733
    response = client_ptr->showCollections("1", "1.1", conncetion_ptr);
B
BossZou 已提交
734 735
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

Y
yukun 已提交
736 737
    response =
        client_ptr->showCollections("0", "9000000000000000000000000000000000000000000000000000000", conncetion_ptr);
B
BossZou 已提交
738 739 740
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
}

G
groot 已提交
741
TEST_F(WebControllerTest, DROP_COLLECTION) {
742
    auto collection_name = "collection_drop_test" + OString(RandomName().c_str());
B
BossZou 已提交
743
    GenCollection(client_ptr, conncetion_ptr, collection_name, 128, 100, "L2");
B
BossZou 已提交
744 745
    sleep(1);

B
BossZou 已提交
746
    auto response = client_ptr->dropCollection(collection_name, conncetion_ptr);
B
BossZou 已提交
747
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
B
BossZou 已提交
748

749
    collection_name = "collection_drop_test_not_exists_" + OString(RandomName().c_str());
B
BossZou 已提交
750
    response = client_ptr->dropCollection(collection_name, conncetion_ptr);
B
BossZou 已提交
751 752
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
    auto error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
753
    ASSERT_EQ(milvus::server::web::StatusCode::COLLECTION_NOT_EXISTS, error_dto->code->getValue());
B
BossZou 已提交
754 755 756
}

TEST_F(WebControllerTest, INSERT) {
757
    auto collection_name = "test_insert_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
758
    const int64_t dim = 64;
B
BossZou 已提交
759
    GenCollection(client_ptr, conncetion_ptr, collection_name, dim, 100, "L2");
B
BossZou 已提交
760

761 762
    nlohmann::json insert_json;
    insert_json["vectors"] = RandomRecordsJson(dim, 20);
B
BossZou 已提交
763

764
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
765 766 767 768
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
    auto result_dto = response->readBodyToDto<milvus::server::web::VectorIdsDto>(object_mapper.get());
    ASSERT_EQ(20, result_dto->ids->count());

769
    response = client_ptr->insert(collection_name + "ooowrweindexsgs", insert_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
770 771
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());

B
BossZou 已提交
772
    response = client_ptr->dropCollection(collection_name, conncetion_ptr);
B
BossZou 已提交
773 774 775
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
}

776
TEST_F(WebControllerTest, INSERT_BIN) {
777
    auto collection_name = "test_insert_bin_collection_test" + OString(RandomName().c_str());
778
    const int64_t dim = 64;
B
BossZou 已提交
779
    GenCollection(client_ptr, conncetion_ptr, collection_name, dim, 100, "HAMMING");
780 781
    nlohmann::json insert_json;
    insert_json["vectors"] = RandomBinRecordsJson(dim, 20);
782
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), conncetion_ptr);
783
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode()) << response->readBodyToString()->std_str();
B
BossZou 已提交
784
    auto status = FlushCollection(client_ptr, conncetion_ptr, collection_name);
785
    ASSERT_TRUE(status.ok()) << status.message();
786 787
    auto result_dto = response->readBodyToDto<milvus::server::web::VectorIdsDto>(object_mapper.get());
    ASSERT_EQ(20, result_dto->ids->count());
B
BossZou 已提交
788
    response = client_ptr->dropCollection(collection_name, conncetion_ptr);
789
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
790

791
    collection_name = "test_insert_bin_collection_test" + OString(RandomName().c_str());
Y
yukun 已提交
792 793
    GenCollection(client_ptr, conncetion_ptr, collection_name, dim, 100,
                  milvus::server::web::NAME_METRIC_TYPE_SUBSTRUCTURE);
794 795
    response = client_ptr->insert(collection_name, insert_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode()) << response->readBodyToString()->std_str();
B
BossZou 已提交
796
    status = FlushCollection(client_ptr, conncetion_ptr, collection_name);
797
    ASSERT_TRUE(status.ok()) << status.message();
B
BossZou 已提交
798
    response = client_ptr->dropCollection(collection_name, conncetion_ptr);
799 800 801
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
}

B
BossZou 已提交
802
TEST_F(WebControllerTest, INSERT_IDS) {
803
    auto collection_name = "test_insert_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
804
    const int64_t dim = 64;
B
BossZou 已提交
805
    GenCollection(client_ptr, conncetion_ptr, collection_name, dim, 100, "L2");
B
BossZou 已提交
806

B
BossZou 已提交
807
    std::vector<std::string> ids;
B
BossZou 已提交
808
    for (size_t i = 0; i < 20; i++) {
B
BossZou 已提交
809
        ids.emplace_back(std::to_string(i));
B
BossZou 已提交
810 811
    }

812 813 814
    nlohmann::json insert_json;
    insert_json["vectors"] = RandomRecordsJson(dim, 20);
    insert_json["ids"] = ids;
B
BossZou 已提交
815

816
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), conncetion_ptr);
817
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode()) << response->readBodyToString()->std_str();
B
BossZou 已提交
818 819 820
    auto result_dto = response->readBodyToDto<milvus::server::web::VectorIdsDto>(object_mapper.get());
    ASSERT_EQ(20, result_dto->ids->count());

B
BossZou 已提交
821
    response = client_ptr->dropCollection(collection_name, conncetion_ptr);
B
BossZou 已提交
822 823 824 825
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
}

TEST_F(WebControllerTest, INDEX) {
826
    auto collection_name = "test_insert_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
827
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");
B
BossZou 已提交
828 829

    // test index with imcomplete param
830
    nlohmann::json index_json;
831
    auto response = client_ptr->createIndex(collection_name, index_json.dump().c_str(), conncetion_ptr);
832
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
833

834
    index_json["index_type"] = milvus::server::web::IndexMap.at(milvus::engine::EngineType::FAISS_IDMAP);
B
BossZou 已提交
835

836
    // missing index `params`
837
    response = client_ptr->createIndex(collection_name, index_json.dump().c_str(), conncetion_ptr);
838
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
839

840
    index_json["params"] = nlohmann::json::parse("{\"nlist\": 10}");
841
    response = client_ptr->createIndex(collection_name, index_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
842
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
843

B
BossZou 已提交
844
    // drop index
845
    response = client_ptr->dropIndex(collection_name, conncetion_ptr);
B
BossZou 已提交
846 847
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

J
Jin Hai 已提交
848
    // create index without existing collection
Y
yukun 已提交
849 850
    response = client_ptr->createIndex(collection_name + "fgafafafafafUUUUUUa124254", index_json.dump().c_str(),
                                       conncetion_ptr);
B
BossZou 已提交
851 852
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());

853 854
    // invalid index type
    index_json["index_type"] = "J46";
855
    response = client_ptr->createIndex(collection_name, index_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
856 857 858 859 860
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
    auto result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::ILLEGAL_INDEX_TYPE, result_dto->code);

    // drop index
861
    response = client_ptr->dropIndex(collection_name, conncetion_ptr);
B
BossZou 已提交
862 863 864
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());

    // insert data and create index
865
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200);
866
    ASSERT_TRUE(status.ok()) << status.message();
B
BossZou 已提交
867

868
    index_json["index_type"] = milvus::server::web::IndexMap.at(milvus::engine::EngineType::FAISS_IVFFLAT);
869
    response = client_ptr->createIndex(collection_name, index_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
870 871 872
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());

    // get index
873
    response = client_ptr->getIndex(collection_name, conncetion_ptr);
B
BossZou 已提交
874
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
875 876 877 878 879 880 881 882 883 884 885 886
    auto result_index_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(result_index_json.contains("index_type"));
    ASSERT_EQ("IVFFLAT", result_index_json["index_type"].get<std::string>());
    ASSERT_TRUE(result_index_json.contains("params"));

    // check index params
    auto params_json = result_index_json["params"];
    ASSERT_TRUE(params_json.contains("nlist"));
    auto nlist_json = params_json["nlist"];
    ASSERT_TRUE(nlist_json.is_number());
    ASSERT_EQ(10, nlist_json.get<int64_t>());

J
Jin Hai 已提交
887
    // get index of collection which not exists
888
    response = client_ptr->getIndex(collection_name + "dfaedXXXdfdfet4t343aa4", conncetion_ptr);
B
BossZou 已提交
889 890
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
    auto error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
891
    ASSERT_EQ(milvus::server::web::StatusCode::COLLECTION_NOT_EXISTS, error_dto->code->getValue());
B
BossZou 已提交
892 893 894
}

TEST_F(WebControllerTest, PARTITION) {
895
    const OString collection_name = "test_controller_partition_" + OString(RandomName().c_str());
B
BossZou 已提交
896
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");
B
BossZou 已提交
897 898

    auto par_param = milvus::server::web::PartitionRequestDto::createShared();
899
    auto response = client_ptr->createPartition(collection_name, par_param);
B
BossZou 已提交
900
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
901 902
    auto error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::BODY_FIELD_LOSS, error_dto->code);
B
BossZou 已提交
903

904
    response = client_ptr->createPartition(collection_name, par_param);
905 906 907
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::BODY_FIELD_LOSS, error_dto->code);
B
BossZou 已提交
908 909

    par_param->partition_tag = "tag01";
910
    response = client_ptr->createPartition(collection_name, par_param);
B
BossZou 已提交
911
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());
912 913
    auto create_result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::SUCCESS, create_result_dto->code);
B
BossZou 已提交
914

915
    response = client_ptr->createPartition(collection_name + "afafanotgitdiexists", par_param);
B
BossZou 已提交
916 917
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
918
    ASSERT_EQ(milvus::server::web::StatusCode::COLLECTION_NOT_EXISTS, error_dto->code);
B
BossZou 已提交
919

920
    // insert 200 vectors into collection with tag = 'tag01'
921
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200, "tag01");
922
    ASSERT_TRUE(status.ok()) << status.message();
B
BossZou 已提交
923 924

    // Show all partitins
B
BossZou 已提交
925
    response = client_ptr->showPartitions(collection_name, "0", "10", "", conncetion_ptr);
B
BossZou 已提交
926
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
927
    auto result_dto = response->readBodyToDto<milvus::server::web::PartitionListDto>(object_mapper.get());
928 929
    ASSERT_EQ(2, result_dto->partitions->count());
    ASSERT_EQ("tag01", result_dto->partitions->get(1)->partition_tag->std_str());
B
BossZou 已提交
930

B
BossZou 已提交
931
    response = client_ptr->showPartitions(collection_name, "0", "-1", "", conncetion_ptr);
B
BossZou 已提交
932
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
933
    response = client_ptr->showPartitions(collection_name, "0.1", "7", "", conncetion_ptr);
B
BossZou 已提交
934
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
935
    response = client_ptr->showPartitions(collection_name, "0", "1.6", "", conncetion_ptr);
B
BossZou 已提交
936
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
937
    response = client_ptr->showPartitions(collection_name, "567a", "1", "", conncetion_ptr);
B
BossZou 已提交
938 939
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

940
    // show without existing collections
B
BossZou 已提交
941
    response = client_ptr->showPartitions(collection_name + "dfafaao990099", "0", "10", "", conncetion_ptr);
B
BossZou 已提交
942 943
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
944
    ASSERT_EQ(milvus::server::web::StatusCode::COLLECTION_NOT_EXISTS, error_dto->code->getValue());
B
BossZou 已提交
945

946
    response = client_ptr->dropPartition(collection_name, "{\"partition_tag\": \"tag01\"}", conncetion_ptr);
B
BossZou 已提交
947
    ASSERT_EQ(OStatus::CODE_204.code, response->getStatusCode());
B
BossZou 已提交
948

949 950
    // drop without existing collections
    response = client_ptr->dropPartition(collection_name + "565755682353464aaasafdsfagagqq1223",
951
                                         "{\"partition_tag\": \"tag01\"}", conncetion_ptr);
B
BossZou 已提交
952
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
B
BossZou 已提交
953 954
}

B
BossZou 已提交
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977
TEST_F(WebControllerTest, PARTITION_FILTER) {
    const OString collection_name = "test_controller_partition_" + OString(RandomName().c_str());
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");

    nlohmann::json body_json;
    body_json["filter"]["partition_tag"] = "tag_not_exists_";
    auto response = client_ptr->showPartitions(collection_name, "0", "10", body_json.dump().c_str());
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
    auto result_dto = response->readBodyToDto<milvus::server::web::PartitionListDto>(object_mapper.get());
    ASSERT_EQ(result_dto->count->getValue(), 0);

    auto par_param = milvus::server::web::PartitionRequestDto::createShared();
    par_param->partition_tag = "tag01";
    response = client_ptr->createPartition(collection_name, par_param);
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode());

    body_json["filter"]["partition_tag"] = "tag01";
    response = client_ptr->showPartitions(collection_name, "0", "10", body_json.dump().c_str());
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
    result_dto = response->readBodyToDto<milvus::server::web::PartitionListDto>(object_mapper.get());
    ASSERT_EQ(result_dto->count->getValue(), 1);
}

978
TEST_F(WebControllerTest, SHOW_SEGMENTS) {
979
    OString collection_name = OString("test_milvus_web_segments_test_") + RandomName().c_str();
980

B
BossZou 已提交
981
    GenCollection(client_ptr, conncetion_ptr, collection_name, 256, 1, "L2");
982

983
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 256, 2000);
984 985
    ASSERT_TRUE(status.ok()) << status.message();

986
    auto response = client_ptr->showSegments(collection_name, "0", "10", "", conncetion_ptr);
987 988 989
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

    // validate result
990 991
    std::string json_str = response->readBodyToString()->c_str();
    auto result_json = nlohmann::json::parse(json_str);
992

993 994 995
    ASSERT_TRUE(result_json.contains("count"));
    ASSERT_TRUE(result_json.contains("segments"));
    auto segments_json = result_json["segments"];
996
    ASSERT_TRUE(segments_json.is_array());
997 998
    auto seg0_json = segments_json[0];
    ASSERT_TRUE(seg0_json.contains("partition_tag"));
Y
yukun 已提交
999
    //    ASSERT_EQ(10, segments_json.size());
1000 1001 1002
}

TEST_F(WebControllerTest, GET_SEGMENT_INFO) {
1003
    OString collection_name = OString("test_milvus_web_get_segment_info_test_") + RandomName().c_str();
1004

B
BossZou 已提交
1005
    GenCollection(client_ptr, conncetion_ptr, collection_name, 16, 1, "L2");
1006

1007
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 2000);
1008 1009
    ASSERT_TRUE(status.ok()) << status.message();

1010
    auto response = client_ptr->showSegments(collection_name, "0", "10", "", conncetion_ptr);
1011 1012 1013
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

    // validate result
1014 1015
    std::string json_str = response->readBodyToString()->c_str();
    auto result_json = nlohmann::json::parse(json_str);
1016

1017
    auto segment0_json = result_json["segments"][0];
1018
    std::string segment_name = segment0_json["name"];
1019 1020

    // get segment ids
1021
    response = client_ptr->getSegmentInfo(collection_name, segment_name.c_str(), "ids", "0", "10");
1022 1023
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

1024 1025
    json_str = response->readBodyToString()->c_str();
    auto ids_result_json = nlohmann::json::parse(json_str);
1026 1027 1028 1029 1030 1031
    ASSERT_TRUE(ids_result_json.contains("ids"));
    auto ids_json = ids_result_json["ids"];
    ASSERT_TRUE(ids_json.is_array());
    ASSERT_EQ(10, ids_json.size());

    // get segment vectors
1032
    response = client_ptr->getSegmentInfo(collection_name, segment_name.c_str(), "vectors", "0", "10");
1033 1034
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

1035 1036
    json_str = response->readBodyToString()->c_str();
    auto vecs_result_json = nlohmann::json::parse(json_str);
1037 1038 1039 1040
    ASSERT_TRUE(vecs_result_json.contains("vectors"));
    auto vecs_json = vecs_result_json["vectors"];
    ASSERT_TRUE(vecs_json.is_array());
    ASSERT_EQ(10, vecs_json.size());
1041

1042 1043
    // non-existent collection
    response = client_ptr->getSegmentInfo(collection_name + "_non_existent", segment_name.c_str(), "ids", "0", "10");
1044
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode()) << response->readBodyToString()->c_str();
1045 1046 1047
}

TEST_F(WebControllerTest, SEGMENT_FILTER) {
1048
    OString collection_name = OString("test_milvus_web_segment_filter_test_") + RandomName().c_str();
B
BossZou 已提交
1049
    GenCollection(client_ptr, conncetion_ptr, collection_name, 16, 1, "L2");
1050

1051
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 1000);
1052 1053
    ASSERT_TRUE(status.ok()) << status.message();

1054
    status = GenPartition(client_ptr, conncetion_ptr, collection_name, "tag01");
1055 1056
    ASSERT_TRUE(status.ok()) << status.message();

1057
    status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 1000, "tag01");
1058 1059
    ASSERT_TRUE(status.ok()) << status.message();

1060
    status = GenPartition(client_ptr, conncetion_ptr, collection_name, "tag02");
1061 1062
    ASSERT_TRUE(status.ok()) << status.message();

1063
    status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 1000, "tag02");
1064 1065 1066
    ASSERT_TRUE(status.ok()) << status.message();

    // show segments filtering tag
1067
    auto response = client_ptr->showSegments(collection_name, "0", "10", "_default", conncetion_ptr);
1068 1069
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

1070 1071
    std::string json_str = response->readBodyToString()->c_str();
    auto result_json = nlohmann::json::parse(json_str);
1072
    ASSERT_TRUE(result_json.contains("count"));
1073

1074 1075 1076 1077 1078
    ASSERT_TRUE(result_json.contains("segments"));
    auto segments_json = result_json["segments"];
    ASSERT_TRUE(segments_json.is_array());
    for (auto& part : segments_json) {
        ASSERT_TRUE(part.contains("partition_tag"));
1079
    }
1080
    ASSERT_EQ("_default", segments_json[0]["partition_tag"].get<std::string>());
1081 1082
}

B
BossZou 已提交
1083
TEST_F(WebControllerTest, SEARCH) {
1084
    const OString collection_name = "test_search_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
1085
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");
B
BossZou 已提交
1086

1087
    // Insert 200 vectors into collection
1088
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200);
1089
    ASSERT_TRUE(status.ok()) << status.message();
1090

1091
    // Create partition and insert 200 vectors into it
1092 1093
    auto par_param = milvus::server::web::PartitionRequestDto::createShared();
    par_param->partition_tag = "tag" + OString(RandomName().c_str());
1094
    auto response = client_ptr->createPartition(collection_name, par_param);
1095
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode())
Y
yukun 已提交
1096
        << "Error: " << response->getStatusDescription()->std_str();
1097

1098
    status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200, par_param->partition_tag->std_str());
1099
    ASSERT_TRUE(status.ok()) << status.message();
1100 1101

    // Test search
1102
    nlohmann::json search_json;
1103
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
1104
    auto error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
1105
    ASSERT_NE(milvus::server::web::StatusCode::SUCCESS, error_dto->code);
1106

1107
    search_json["search"]["params"]["nprobe"] = 1;
1108
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
1109 1110 1111
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
    ASSERT_EQ(milvus::server::web::StatusCode::BODY_FIELD_LOSS, error_dto->code);

1112
    search_json["search"]["topk"] = 1;
1113
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
1114
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
1115
    ASSERT_NE(milvus::server::web::StatusCode::SUCCESS, error_dto->code);
1116

1117
    search_json["search"]["vectors"] = RandomRecordsJson(64, 10);
1118
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
1119
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131

    auto result_json = nlohmann::json::parse(response->readBodyToString()->std_str());
    ASSERT_TRUE(result_json.contains("num"));
    ASSERT_TRUE(result_json["num"].is_number());
    ASSERT_EQ(10, result_json["num"].get<int64_t>());

    ASSERT_TRUE(result_json.contains("result"));
    ASSERT_TRUE(result_json["result"].is_array());

    auto result0_json = result_json["result"][0];
    ASSERT_TRUE(result0_json.is_array());
    ASSERT_EQ(1, result0_json.size());
1132 1133

    // Test search with tags
1134 1135 1136 1137
    nlohmann::json par_json;
    par_json.push_back(par_param->partition_tag->std_str());
    search_json["search"]["partition_tags"] = par_json;

1138
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
1139
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
B
BossZou 已提交
1140

1141 1142
    // Test search without existing collection
    response = client_ptr->vectorsOp(collection_name + "999piyanning", search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1143 1144
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode());
    error_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
G
groot 已提交
1145
    ASSERT_EQ(milvus::server::web::StatusCode::COLLECTION_NOT_EXISTS, error_dto->code->getValue());
1146 1147 1148
}

TEST_F(WebControllerTest, SEARCH_BIN) {
1149
    const OString collection_name = "test_search_bin_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
1150
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "HAMMING");
1151

1152
    // Insert 200 vectors into collection
1153
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200, "", true);
1154
    ASSERT_TRUE(status.ok()) << status.message();
B
BossZou 已提交
1155

1156
    // Create partition and insert 200 vectors into it
B
BossZou 已提交
1157 1158
    auto par_param = milvus::server::web::PartitionRequestDto::createShared();
    par_param->partition_tag = "tag" + OString(RandomName().c_str());
1159
    auto response = client_ptr->createPartition(collection_name, par_param);
B
BossZou 已提交
1160
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode())
Y
yukun 已提交
1161
        << "Error: " << response->readBodyToString()->std_str();
B
BossZou 已提交
1162

1163 1164
    status =
        InsertData(client_ptr, conncetion_ptr, collection_name, 64, 200, par_param->partition_tag->std_str(), true);
1165
    ASSERT_TRUE(status.ok()) << status.message();
B
BossZou 已提交
1166 1167

    // Test search
1168
    nlohmann::json search_json;
1169
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1170
    auto result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
1171
    ASSERT_NE(milvus::server::web::StatusCode::SUCCESS, result_dto->code);
B
BossZou 已提交
1172

1173
    search_json["search"]["params"]["nprobe"] = 1;
1174
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1175
    result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
1176
    ASSERT_NE(milvus::server::web::StatusCode::SUCCESS, result_dto->code);
B
BossZou 已提交
1177

1178
    search_json["search"]["topk"] = 1;
1179
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1180
    result_dto = response->readBodyToDto<milvus::server::web::StatusDto>(object_mapper.get());
1181
    ASSERT_NE(milvus::server::web::StatusCode::SUCCESS, result_dto->code);
B
BossZou 已提交
1182

1183
    search_json["search"]["vectors"] = RandomBinRecordsJson(64, 10);
1184
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1185 1186
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
    // validate search result
    auto result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(result_json.contains("result"));
    ASSERT_TRUE(result_json["result"].is_array());
    ASSERT_EQ(10, result_json["result"].size());

    auto result0_json = result_json["result"][0];
    ASSERT_TRUE(result0_json.is_array());
    ASSERT_EQ(1, result0_json.size());

B
BossZou 已提交
1197
    // Test search with tags
1198 1199
    search_json["search"]["partition_tags"] = std::vector<std::string>();
    search_json["search"]["partition_tags"].push_back(par_param->partition_tag->std_str());
1200
    response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1201 1202 1203
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
}

B
BossZou 已提交
1204 1205
TEST_F(WebControllerTest, SEARCH_BY_IDS) {
#ifdef MILVUS_GPU_VERSION
Y
yukun 已提交
1206
    auto& config = milvus::server::Config::GetInstance();
B
BossZou 已提交
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
    auto config_status = config.SetGpuResourceConfigEnable("false");
    ASSERT_TRUE(config_status.ok()) << config_status.message();
#endif

    const OString collection_name = "test_search_by_ids_collection_test_" + OString(RandomName().c_str());
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");

    // Insert 100 vectors into collection
    std::vector<std::string> ids;
    for (size_t i = 0; i < 100; i++) {
        ids.emplace_back(std::to_string(i));
    }

    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 100, ids);
    ASSERT_TRUE(status.ok()) << status.message();

    nlohmann::json search_json;
    search_json["search"]["topk"] = 1;
    search_json["search"]["ids"] = std::vector<std::string>(ids.begin(), ids.begin() + 10);
    search_json["search"]["params"] = "{\"nprobe\": 1}";

    auto response = client_ptr->vectorsOp(collection_name, search_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

    // validate search result
    auto result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(result_json.contains("result"));
    ASSERT_TRUE(result_json["result"].is_array());
    ASSERT_EQ(10, result_json["result"].size());

Y
yukun 已提交
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
    //    for (size_t j = 0; j < 10; j++) {
    //        auto result0_json = result_json["result"][0];
    //        ASSERT_TRUE(result0_json.is_array());
    //        ASSERT_EQ(1, result0_json.size());
    //
    //        auto result0_top0_json = result0_json[0];
    //        ASSERT_TRUE(result0_top0_json.contains("id"));
    //
    //        auto id = result0_top0_json["id"];
    //        ASSERT_TRUE(id.is_string());
    //        ASSERT_EQ(std::to_string(ids.at(j)), id.get<std::string>());
    //    }
B
BossZou 已提交
1249
}
1250

B
BossZou 已提交
1251
TEST_F(WebControllerTest, GET_VECTORS_BY_IDS) {
1252
    const OString collection_name = "test_milvus_web_get_vector_by_id_test_" + OString(RandomName().c_str());
B
BossZou 已提交
1253
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");
1254

1255
    // Insert 100 vectors into collection
B
BossZou 已提交
1256
    std::vector<std::string> ids;
1257
    for (size_t i = 0; i < 100; i++) {
B
BossZou 已提交
1258
        ids.emplace_back(std::to_string(i));
1259 1260
    }

1261
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 64, 100, ids);
1262 1263 1264
    ASSERT_TRUE(status.ok()) << status.message();

    /* test task load */
B
BossZou 已提交
1265 1266 1267 1268
    std::vector<std::string> vector_ids;
    for (size_t i = 0; i < 10; i++) {
        vector_ids.emplace_back(ids.at(i));
    }
1269 1270 1271 1272

    std::string query_ids;
    milvus::server::StringHelpFunctions::MergeStringWithDelimeter(vector_ids, ",", query_ids);
    auto response = client_ptr->getVectors(collection_name, query_ids.c_str(), conncetion_ptr);
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

    // validate result
    auto result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(result_json.contains("vectors"));

    auto vectors_json = result_json["vectors"];
    ASSERT_TRUE(vectors_json.is_array());

    auto vector_json = vectors_json[0];
    ASSERT_TRUE(vector_json.contains("id"));
B
BossZou 已提交
1284
    ASSERT_EQ(ids[0], vector_json["id"].get<std::string>());
1285 1286 1287 1288 1289
    ASSERT_TRUE(vector_json.contains("vector"));

    auto vec_json = vector_json["vector"];
    ASSERT_TRUE(vec_json.is_array());
    std::vector<int64_t> vec;
1290
    for (auto& v : vec_json) {
1291 1292 1293 1294
        vec.emplace_back(v.get<int64_t>());
    }

    ASSERT_EQ(64, vec.size());
1295

1296
    // non-existent collection
1297
    response = client_ptr->getVectors(collection_name + "_non_existent", query_ids.c_str(), conncetion_ptr);
1298
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode()) << response->readBodyToString()->c_str();
1299 1300 1301
}

TEST_F(WebControllerTest, DELETE_BY_ID) {
1302
    const OString collection_name = "test_search_bin_collection_test" + OString(RandomName().c_str());
B
BossZou 已提交
1303
    GenCollection(client_ptr, conncetion_ptr, collection_name, 64, 100, "L2");
1304

1305
    // Insert 200 vectors into collection
1306 1307
    nlohmann::json insert_json;
    insert_json["vectors"] = RandomRecordsJson(64, 2000);
1308
    auto response = client_ptr->insert(collection_name, insert_json.dump().c_str(), conncetion_ptr);
1309 1310 1311 1312 1313 1314 1315
    ASSERT_EQ(OStatus::CODE_201.code, response->getStatusCode()) << response->readBodyToString()->c_str();

    auto insert_result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(insert_result_json.contains("ids"));
    auto ids_json = insert_result_json["ids"];
    ASSERT_TRUE(ids_json.is_array());

1316
    std::vector<std::string> ids;
1317
    for (auto& id : ids_json) {
1318
        ids.emplace_back(id.get<std::string>());
1319 1320
    }

1321
    auto delete_ids = std::vector<std::string>(ids.begin(), ids.begin() + 10);
1322 1323 1324 1325

    nlohmann::json delete_json;
    delete_json["delete"]["ids"] = delete_ids;

1326
    response = client_ptr->vectorsOp(collection_name, delete_json.dump().c_str(), conncetion_ptr);
1327
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
1328

1329 1330
    // non-existent collection
    response = client_ptr->vectorsOp(collection_name + "_non_existent", delete_json.dump().c_str(), conncetion_ptr);
1331
    ASSERT_EQ(OStatus::CODE_404.code, response->getStatusCode()) << response->readBodyToString()->c_str();
1332 1333
}

B
BossZou 已提交
1334
TEST_F(WebControllerTest, CMD) {
1335 1336 1337 1338 1339 1340
    auto response = client_ptr->cmd("status", "", "", conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    response = client_ptr->cmd("version", "", "", conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

1341
    // test invalid body
1342
    response = client_ptr->cmd("mode", "", "", conncetion_ptr);
B
BossZou 已提交
1343 1344
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

1345
    response = client_ptr->cmd("taskcollection", "", "", conncetion_ptr);
B
BossZou 已提交
1346
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
1347 1348 1349

    response = client_ptr->cmd("info", "", "", conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
1350 1351
}

1352
TEST_F(WebControllerTest, CONFIG) {
1353 1354 1355 1356
    std::string config_path = std::string(CONTROLLER_TEST_CONFIG_DIR).append(CONTROLLER_TEST_CONFIG_FILE);
    std::fstream fs(config_path.c_str(), std::ios_base::out);
    fs << CONTROLLER_TEST_VALID_CONFIG_STR;
    fs.flush();
1357
    fs.close();
1358 1359 1360 1361 1362

    milvus::server::Config& config = milvus::server::Config::GetInstance();
    auto status = config.LoadConfigFile(config_path);
    ASSERT_TRUE(status.ok()) << status.message();

1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
#ifdef MILVUS_GPU_VERSION
    status = config.SetGpuResourceConfigEnable("true");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigCacheCapacity("1");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigBuildIndexResources("gpu0");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigSearchResources("gpu0");
    ASSERT_TRUE(status.ok()) << status.message();
#endif
1373

1374 1375
    auto response = client_ptr->cmd("config", "", "", conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
1376 1377 1378
    auto result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
    ASSERT_TRUE(result_json.contains("restart_required"));

1379
    OString collection_name = "milvus_test_webcontroller_test_preload_collection";
B
BossZou 已提交
1380
    GenCollection(client_ptr, conncetion_ptr, collection_name, 16, 10, "L2");
1381

1382
    OString collection_name_s = "milvus_test_webcontroller_test_preload_collection_s";
B
BossZou 已提交
1383
    GenCollection(client_ptr, conncetion_ptr, collection_name_s, 16, 10, "L2");
1384

W
Wang XiangYu 已提交
1385
    OString body_str = "{\"cache\": {\"preload_collection\": \"" + collection_name + "\"}}";
1386 1387 1388
    response = client_ptr->op("config", body_str, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();

W
Wang XiangYu 已提交
1389
    body_str = "{\"cache\": {\"preload_collection\": \"" + collection_name + "," + collection_name_s + "\"}}";
1390 1391 1392
    response = client_ptr->op("config", body_str, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
    auto set_result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
C
Cai Yudong 已提交
1393 1394 1395 1396 1397 1398 1399 1400
//    ASSERT_TRUE(set_result_json.contains("restart_required"));
//    ASSERT_EQ(true, set_result_json["restart_required"].get<bool>());

//    response = client_ptr->cmd("config", "", "", conncetion_ptr);
//    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
//    auto get_result_json = nlohmann::json::parse(response->readBodyToString()->c_str());
//    ASSERT_TRUE(get_result_json.contains("restart_required"));
//    ASSERT_EQ(true, get_result_json["restart_required"].get<bool>());
B
BossZou 已提交
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411

    fiu_init(0);
    fiu_enable("WebRequestHandler.SystemOp.raise_parse_error", 1, NULL, 0);
    response = client_ptr->op("config", body_str, conncetion_ptr);
    ASSERT_NE(OStatus::CODE_200.code, response->getStatusCode());
    fiu_disable("WebRequestHandler.SystemOp.raise_parse_error");

    fiu_enable("WebRequestHandler.SystemOp.raise_type_error", 1, NULL, 0);
    response = client_ptr->op("config", body_str, conncetion_ptr);
    ASSERT_NE(OStatus::CODE_200.code, response->getStatusCode());
    fiu_disable("WebRequestHandler.SystemOp.raise_type_error");
B
BossZou 已提交
1412 1413
}

B
BossZou 已提交
1414
TEST_F(WebControllerTest, ADVANCED_CONFIG) {
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424
    std::string config_path = std::string(CONTROLLER_TEST_CONFIG_DIR).append(CONTROLLER_TEST_CONFIG_FILE);
    std::fstream fs(config_path.c_str(), std::ios_base::out);
    fs << CONTROLLER_TEST_VALID_CONFIG_STR;
    fs.flush();
    fs.close();

    milvus::server::Config& config = milvus::server::Config::GetInstance();
    auto status = config.LoadConfigFile(config_path);
    ASSERT_TRUE(status.ok()) << status.message();

B
BossZou 已提交
1425 1426 1427 1428 1429 1430
    auto response = client_ptr->getAdvanced(conncetion_ptr);

    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    auto config_dto = milvus::server::web::AdvancedConfigDto::createShared();
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
W
Wang XiangYu 已提交
1431
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
B
BossZou 已提交
1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449

    config_dto->cpu_cache_capacity = 3;
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    config_dto->cache_insert_data = true;
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

#ifdef MILVUS_GPU_VERSION
    config_dto->gpu_search_threshold = 1000;
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
#endif

    config_dto->use_blas_threshold = 1000;
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
B
BossZou 已提交
1450

1451
    // test fault
B
BossZou 已提交
1452
    // cpu cache capacity exceed total memory
Y
yukun 已提交
1453
    config_dto->cpu_cache_capacity = 10000L * (1024L * 1024 * 1024);  // 10000 GB
B
BossZou 已提交
1454 1455
    response = client_ptr->setAdvanced(config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
1456 1457 1458
}

#ifdef MILVUS_GPU_VERSION
B
BossZou 已提交
1459
TEST_F(WebControllerTest, GPU_CONFIG) {
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
    std::string config_path = std::string(CONTROLLER_TEST_CONFIG_DIR).append(CONTROLLER_TEST_CONFIG_FILE);
    std::fstream fs(config_path.c_str(), std::ios_base::out);
    fs << CONTROLLER_TEST_VALID_CONFIG_STR;
    fs.flush();
    fs.close();

    milvus::server::Config& config = milvus::server::Config::GetInstance();
    auto status = config.LoadConfigFile(config_path);
    ASSERT_TRUE(status.ok()) << status.message();

    status = config.SetGpuResourceConfigEnable("true");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigCacheCapacity("1");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigBuildIndexResources("gpu0");
    ASSERT_TRUE(status.ok()) << status.message();
    status = config.SetGpuResourceConfigSearchResources("gpu0");
    ASSERT_TRUE(status.ok()) << status.message();

B
BossZou 已提交
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504
    auto response = client_ptr->getGPUConfig(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    auto gpu_config_dto = milvus::server::web::GPUConfigDto::createShared();

    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    gpu_config_dto->enable = true;
    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    gpu_config_dto->cache_capacity = 2;
    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    gpu_config_dto->build_index_resources = gpu_config_dto->build_index_resources->createShared();
    gpu_config_dto->build_index_resources->pushBack("GPU0");
    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    gpu_config_dto->search_resources = gpu_config_dto->search_resources->createShared();
    gpu_config_dto->search_resources->pushBack("GPU0");

    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
B
BossZou 已提交
1505 1506

    //// test fault config
W
Wang XiangYu 已提交
1507
    // cache capacity exceed GPU mem size (GiB)
Y
yukun 已提交
1508
    gpu_config_dto->cache_capacity = 100000L * 1024 * 1024 * 1024;  // 100000 GiB
B
BossZou 已提交
1509
    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
W
Wang XiangYu 已提交
1510
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode()) << response->readBodyToString()->c_str();
B
BossZou 已提交
1511 1512 1513 1514 1515 1516 1517 1518 1519
    gpu_config_dto->cache_capacity = 1;

    // duplicate resources
    gpu_config_dto->search_resources->clear();
    gpu_config_dto->search_resources->pushBack("GPU0");
    gpu_config_dto->search_resources->pushBack("GPU1");
    gpu_config_dto->search_resources->pushBack("GPU0");
    response = client_ptr->setGPUConfig(gpu_config_dto, conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
1520 1521 1522
}
#endif

B
BossZou 已提交
1523
TEST_F(WebControllerTest, DEVICES_CONFIG) {
1524 1525 1526 1527 1528
    auto response = client_ptr->getDevices(conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
}

TEST_F(WebControllerTest, FLUSH) {
G
groot 已提交
1529
    auto collection_name = milvus::server::web::OString(COLLECTION_NAME) + RandomName().c_str();
B
BossZou 已提交
1530
    GenCollection(client_ptr, conncetion_ptr, collection_name, 16, 10, "L2");
1531

1532
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 1000);
1533 1534 1535
    ASSERT_TRUE(status.ok()) << status.message();

    nlohmann::json flush_json;
1536
    flush_json["flush"]["collection_names"] = {collection_name->std_str()};
1537
    auto response = client_ptr->op("task", flush_json.dump().c_str(), conncetion_ptr);
B
BossZou 已提交
1538
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());
1539 1540

    // invalid payload format
1541
    flush_json["flush"]["collection_names"] = collection_name->std_str();
1542 1543 1544 1545
    response = client_ptr->op("task", flush_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());

    // non-existent name
1546
    flush_json["flush"]["collection_names"] = {"afafaf444353"};
1547 1548 1549 1550 1551
    response = client_ptr->op("task", flush_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
}

TEST_F(WebControllerTest, COMPACT) {
1552
    auto collection_name = milvus::server::web::OString("milvus_web_test_compact_") + RandomName().c_str();
B
BossZou 已提交
1553
    GenCollection(client_ptr, conncetion_ptr, collection_name, 16, 10, "L2");
1554

1555
    auto status = InsertData(client_ptr, conncetion_ptr, collection_name, 16, 1000);
1556 1557 1558
    ASSERT_TRUE(status.ok()) << status.message();

    nlohmann::json compact_json;
1559
    compact_json["compact"]["collection_name"] = collection_name->std_str();
1560 1561 1562 1563 1564
    auto response = client_ptr->op("task", compact_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode()) << response->readBodyToString()->c_str();
}

TEST_F(WebControllerTest, LOAD) {
1565
    OString collection_name = "milvus_web_test_load_" + OString(RandomName().c_str());
B
BossZou 已提交
1566
    GenCollection(client_ptr, conncetion_ptr, collection_name, 128, 100, "L2");
1567 1568

    nlohmann::json load_json;
1569
    load_json["load"]["collection_name"] = collection_name->c_str();
1570 1571 1572 1573
    auto response = client_ptr->op("task", load_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_200.code, response->getStatusCode());

    // load with a non-existent name
1574
    load_json["load"]["collection_name"] = "sssssssssssssssssssssssfsfsfsrrrttt";
1575 1576
    response = client_ptr->op("task", load_json.dump().c_str(), conncetion_ptr);
    ASSERT_EQ(OStatus::CODE_400.code, response->getStatusCode());
B
BossZou 已提交
1577
}