couchbase 3.2.2 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/binding.gyp +5 -0
  2. package/deps/lcb/CMakeLists.txt +1 -1
  3. package/deps/lcb/CONTRIBUTING.md +1 -1
  4. package/deps/lcb/README.markdown +2 -2
  5. package/deps/lcb/RELEASE_NOTES.markdown +84 -17
  6. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  7. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  8. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
  9. package/deps/lcb/doc/Doxyfile +1 -1
  10. package/deps/lcb/example/minimal/query.c +9 -7
  11. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  12. package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
  13. package/deps/lcb/include/libcouchbase/couchbase.h +55 -1
  14. package/deps/lcb/include/libcouchbase/error.h +6 -1
  15. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  16. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  17. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  18. package/deps/lcb/libcouchbase.gyp +353 -349
  19. package/deps/lcb/packaging/deb/control +1 -1
  20. package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
  21. package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
  22. package/deps/lcb/src/capi/cmd_counter.hh +18 -0
  23. package/deps/lcb/src/capi/cmd_exists.hh +18 -0
  24. package/deps/lcb/src/capi/cmd_get.hh +17 -0
  25. package/deps/lcb/src/capi/cmd_get_replica.hh +20 -1
  26. package/deps/lcb/src/capi/cmd_query.cc +13 -0
  27. package/deps/lcb/src/capi/cmd_query.hh +22 -14
  28. package/deps/lcb/src/capi/cmd_remove.hh +18 -0
  29. package/deps/lcb/src/capi/cmd_search.hh +6 -0
  30. package/deps/lcb/src/capi/cmd_store.hh +28 -21
  31. package/deps/lcb/src/capi/cmd_subdoc.hh +30 -0
  32. package/deps/lcb/src/capi/cmd_touch.hh +18 -0
  33. package/deps/lcb/src/capi/cmd_unlock.hh +18 -0
  34. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  35. package/deps/lcb/src/capi/collection_qualifier.hh +6 -8
  36. package/deps/lcb/src/cntl.cc +42 -8
  37. package/deps/lcb/src/dns-srv.cc +5 -3
  38. package/deps/lcb/src/errmap.cc +5 -9
  39. package/deps/lcb/src/errmap.h +7 -3
  40. package/deps/lcb/src/handler.cc +24 -18
  41. package/deps/lcb/src/internal.h +2 -1
  42. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  43. package/deps/lcb/src/mcserver/mcserver.cc +8 -5
  44. package/deps/lcb/src/mcserver/negotiate.cc +42 -17
  45. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  46. package/deps/lcb/src/n1ql/n1ql.cc +5 -1
  47. package/deps/lcb/src/n1ql/query_handle.cc +80 -44
  48. package/deps/lcb/src/n1ql/query_handle.hh +41 -3
  49. package/deps/lcb/src/operations/counter.cc +13 -1
  50. package/deps/lcb/src/operations/exists.cc +14 -2
  51. package/deps/lcb/src/operations/get.cc +14 -2
  52. package/deps/lcb/src/operations/get_replica.cc +18 -6
  53. package/deps/lcb/src/operations/observe.cc +1 -1
  54. package/deps/lcb/src/operations/remove.cc +13 -1
  55. package/deps/lcb/src/operations/store.cc +13 -1
  56. package/deps/lcb/src/operations/subdoc.cc +13 -2
  57. package/deps/lcb/src/operations/touch.cc +14 -2
  58. package/deps/lcb/src/operations/unlock.cc +14 -2
  59. package/deps/lcb/src/search/search_handle.cc +26 -8
  60. package/deps/lcb/src/search/search_handle.hh +29 -0
  61. package/deps/lcb/src/ssl/ssl_common.c +7 -8
  62. package/deps/lcb/src/tracing/span.cc +43 -10
  63. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  64. package/deps/lcb/src/utilities.cc +21 -0
  65. package/deps/lcb/src/utilities.h +3 -0
  66. package/deps/lcb/src/views/view_handle.cc +13 -5
  67. package/deps/lcb/src/views/view_handle.hh +29 -0
  68. package/deps/lcb/tests/CMakeLists.txt +21 -0
  69. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  70. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  71. package/deps/lcb/tests/iotests/mock-environment.cc +25 -1
  72. package/deps/lcb/tests/iotests/mock-environment.h +49 -1
  73. package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
  74. package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
  75. package/deps/lcb/tests/iotests/serverparams.h +7 -2
  76. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  77. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  78. package/deps/lcb/tests/iotests/t_get.cc +14 -4
  79. package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
  80. package/deps/lcb/tests/iotests/t_ratelimit.cc +729 -0
  81. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  82. package/deps/lcb/tests/iotests/testutil.cc +342 -0
  83. package/deps/lcb/tests/iotests/testutil.h +164 -0
  84. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  85. package/deps/lcb/tests/mocksupport/server.c +0 -1
  86. package/deps/lcb/tools/cbc.cc +7 -0
  87. package/dist/analyticsexecutor.js +2 -2
  88. package/dist/analyticsindexmanager.js +512 -524
  89. package/dist/binarycollection.d.ts +17 -0
  90. package/dist/binding.d.ts +2 -0
  91. package/dist/binding.js +1 -1
  92. package/dist/bindingutilities.js +9 -1
  93. package/dist/bucketmanager.d.ts +32 -23
  94. package/dist/bucketmanager.js +197 -189
  95. package/dist/cluster.js +37 -36
  96. package/dist/collection.js +17 -23
  97. package/dist/collectionmanager.js +181 -200
  98. package/dist/connection.js +6 -3
  99. package/dist/connspec.js +5 -1
  100. package/dist/couchbase.js +7 -14
  101. package/dist/datastructures.js +239 -310
  102. package/dist/diagnosticsexecutor.js +70 -85
  103. package/dist/errors.d.ts +18 -0
  104. package/dist/errors.js +26 -2
  105. package/dist/eventingfunctionmanager.js +267 -294
  106. package/dist/httpexecutor.js +31 -38
  107. package/dist/logging.js +1 -1
  108. package/dist/queryexecutor.js +3 -3
  109. package/dist/queryindexmanager.js +236 -263
  110. package/dist/scope.js +8 -2
  111. package/dist/searchexecutor.js +3 -0
  112. package/dist/searchindexmanager.js +240 -271
  113. package/dist/searchquery.d.ts +17 -0
  114. package/dist/searchquery.js +22 -1
  115. package/dist/searchtypes.d.ts +7 -2
  116. package/dist/searchtypes.js +2 -2
  117. package/dist/usermanager.js +250 -263
  118. package/dist/utilities.d.ts +3 -2
  119. package/dist/utilities.js +16 -4
  120. package/dist/viewexecutor.js +1 -1
  121. package/dist/viewindexmanager.js +131 -150
  122. package/package.json +1 -1
  123. package/src/connection.cpp +2 -0
  124. package/src/constants.cpp +2 -0
  125. package/src/instance.cpp +8 -1
  126. package/src/instance.h +1 -0
  127. package/src/uv-plugin-all.cpp +1 -0
  128. package/dist/cas.d.ts +0 -0
  129. package/dist/cas.js +0 -1
@@ -243,6 +243,7 @@ TEST_F(ViewsUnitTest, testSimpleView)
243
243
  {
244
244
  SKIP_UNLESS_MOCK();
245
245
  // Requires beer-sample
246
+ MockEnvironment *mock = MockEnvironment::getInstance();
246
247
  HandleWrap hw;
247
248
  lcb_INSTANCE *instance;
248
249
  connectBeerSample(hw, &instance);
@@ -316,6 +316,10 @@ static std::uint64_t get_manifest_id(lcb_INSTANCE *instance)
316
316
  lcb_cmdgetmanifest_destroy(cmd);
317
317
  lcb_wait(instance, LCB_WAIT_DEFAULT);
318
318
 
319
+ if (result.rc == LCB_ERR_TIMEOUT) {
320
+ return 0;
321
+ }
322
+
319
323
  Json::Value payload;
320
324
  EXPECT_EQ(LCB_SUCCESS, result.rc);
321
325
  EXPECT_FALSE(result.value.empty());
@@ -461,3 +465,341 @@ std::string unique_name(const std::string &prefix)
461
465
  ss << prefix << lcb_next_rand32();
462
466
  return ss.str();
463
467
  }
468
+
469
+ void TestSpan::SetAttribute(std::string key, uint64_t value)
470
+ {
471
+ int_tags[std::move(key)] = value;
472
+ }
473
+
474
+ void TestSpan::SetAttribute(std::string key, std::string value)
475
+ {
476
+ str_tags[std::move(key)] = std::move(value);
477
+ }
478
+
479
+ void TestSpan::End()
480
+ {
481
+ finished = true;
482
+ }
483
+
484
+ TestSpan::TestSpan(std::string span_name)
485
+ {
486
+ name = std::move(span_name);
487
+ }
488
+
489
+ std::shared_ptr<TestSpan> TestTracer::StartSpan(std::string name)
490
+ {
491
+ auto t_span = std::make_shared<TestSpan>(name);
492
+ spans.push_back(t_span);
493
+ return t_span;
494
+ }
495
+
496
+ void TestTracer::reset()
497
+ {
498
+ spans.clear();
499
+ }
500
+
501
+ static void *start_span(lcbtrace_TRACER *tracer, const char *name, void *parent)
502
+ {
503
+ auto test_tracer = static_cast<TestTracer *>(tracer->cookie);
504
+ if (!test_tracer->enabled()) {
505
+ return nullptr;
506
+ }
507
+ auto test_span = test_tracer->StartSpan(std::string(name));
508
+ return test_span.get();
509
+ }
510
+
511
+ static void end_span(void *span)
512
+ {
513
+ if (span == nullptr) {
514
+ return;
515
+ }
516
+ static_cast<TestSpan *>(span)->End();
517
+ }
518
+
519
+ static void add_tag_string(void *span, const char *name, const char *value, size_t value_len)
520
+ {
521
+ if (span == nullptr) {
522
+ return;
523
+ }
524
+ std::string val;
525
+ val.append(value, value_len);
526
+ static_cast<TestSpan *>(span)->SetAttribute(std::string(name), val);
527
+ }
528
+
529
+ static void add_tag_uint64(void *span, const char *name, uint64_t value)
530
+ {
531
+ if (span == nullptr) {
532
+ return;
533
+ }
534
+ static_cast<TestSpan *>(span)->SetAttribute(name, value);
535
+ }
536
+
537
+ void TestTracer::create_lcb_tracer()
538
+ {
539
+ lcbtracer_ = lcbtrace_new(nullptr, LCBTRACE_F_EXTERNAL);
540
+ lcbtracer_->version = 1;
541
+ lcbtracer_->v.v1.start_span = start_span;
542
+ lcbtracer_->v.v1.end_span = end_span;
543
+ lcbtracer_->v.v1.add_tag_string = add_tag_string;
544
+ lcbtracer_->v.v1.add_tag_uint64 = add_tag_uint64;
545
+ lcbtracer_->cookie = static_cast<void *>(this);
546
+ }
547
+
548
+ void TestTracer::destroy_lcb_tracer()
549
+ {
550
+ if (lcbtracer_ != nullptr) {
551
+ lcbtrace_destroy(lcbtracer_);
552
+ delete lcbtracer_;
553
+ lcbtracer_ = nullptr;
554
+ }
555
+ }
556
+
557
+ TestTracer::~TestTracer()
558
+ {
559
+ destroy_lcb_tracer();
560
+ }
561
+
562
+ TestMeter::TestMeter() = default;
563
+
564
+ void TestMeter::reset()
565
+ {
566
+ recorders.clear();
567
+ }
568
+
569
+ void TestValueRecorder::RecordValue(uint64_t value)
570
+ {
571
+ values.push_back(value);
572
+ }
573
+
574
+ std::shared_ptr<TestValueRecorder> TestMeter::ValueRecorder(std::string name,
575
+ std::unordered_map<std::string, std::string> tags)
576
+ {
577
+ auto key = name + ":" + tags["db.couchbase.service"];
578
+ auto op = tags["db.operation"];
579
+ if (!op.empty()) {
580
+ key = key + ":" + op;
581
+ }
582
+ std::shared_ptr<TestValueRecorder> test_recorder;
583
+ if (recorders.find(key) == recorders.end()) {
584
+ test_recorder = std::make_shared<TestValueRecorder>();
585
+ recorders[key] = test_recorder;
586
+ } else {
587
+ test_recorder = recorders[key];
588
+ }
589
+ return test_recorder;
590
+ }
591
+
592
+ static void record_callback(const lcbmetrics_VALUERECORDER *recorder, uint64_t value)
593
+ {
594
+ void *test_recorder;
595
+ lcbmetrics_valuerecorder_cookie(recorder, &test_recorder);
596
+ static_cast<TestValueRecorder *>(test_recorder)->RecordValue(value);
597
+ }
598
+
599
+ static const lcbmetrics_VALUERECORDER *new_recorder(const lcbmetrics_METER *meter, const char *name,
600
+ const lcbmetrics_TAG *tags, size_t ntags)
601
+ {
602
+ std::unordered_map<std::string, std::string> recorder_tags;
603
+ for (int i = 0; i < ntags; i++) {
604
+ recorder_tags[tags[i].key] = tags[i].value;
605
+ }
606
+
607
+ void *test_meter_;
608
+ lcbmetrics_meter_cookie(meter, &test_meter_);
609
+ auto test_meter = static_cast<TestMeter *>(test_meter_);
610
+ auto test_value_recorder = test_meter->ValueRecorder(std::string(name), recorder_tags);
611
+
612
+ lcbmetrics_VALUERECORDER *recorder;
613
+ lcbmetrics_valuerecorder_create(&recorder, test_value_recorder.get());
614
+ lcbmetrics_valuerecorder_record_value_callback(recorder, record_callback);
615
+
616
+ return recorder;
617
+ }
618
+
619
+ void TestMeter::create_lcb_meter()
620
+ {
621
+ lcbmetrics_meter_create(&lcbmeter_, static_cast<void *>(this));
622
+ lcbmetrics_meter_value_recorder_callback(lcbmeter_, new_recorder);
623
+ }
624
+
625
+ void TestMeter::destroy_lcb_meter()
626
+ {
627
+ if (lcbmeter_ != nullptr) {
628
+ lcbmetrics_meter_destroy(lcbmeter_);
629
+ lcbmeter_ = nullptr;
630
+ }
631
+ }
632
+
633
+ void enforce_rate_limits(lcb_INSTANCE *instance)
634
+ {
635
+ (void)lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback);
636
+
637
+ lcb_CMDHTTP *cmd;
638
+ std::string path = "/internalSettings";
639
+ std::string body = "enforceLimits=true";
640
+
641
+ lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_MANAGEMENT);
642
+ lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_POST);
643
+ lcb_cmdhttp_path(cmd, path.c_str(), path.size());
644
+ lcb_cmdhttp_body(cmd, body.c_str(), body.size());
645
+
646
+ http_result result{};
647
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_http(instance, &result, cmd));
648
+ lcb_cmdhttp_destroy(cmd);
649
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_wait(instance, LCB_WAIT_DEFAULT));
650
+ ASSERT_STATUS_EQ(LCB_SUCCESS, result.rc);
651
+ }
652
+
653
+ void create_rate_limited_user(lcb_INSTANCE *instance, const std::string &username, const rate_limits &limits)
654
+ {
655
+ (void)lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback);
656
+
657
+ lcb_CMDHTTP *cmd;
658
+ std::string path = "/settings/rbac/users/local/" + username;
659
+ std::string body = "password=password&roles=admin";
660
+ Json::Value json_limits;
661
+ if (limits.kv_limits.enforce) {
662
+ Json::Value kv_limits;
663
+ if (limits.kv_limits.num_connections > 0) {
664
+ kv_limits["num_connections"] = limits.kv_limits.num_connections;
665
+ }
666
+ if (limits.kv_limits.num_ops_per_min > 0) {
667
+ kv_limits["num_ops_per_min"] = limits.kv_limits.num_ops_per_min;
668
+ }
669
+ if (limits.kv_limits.ingress_mib_per_min > 0) {
670
+ kv_limits["ingress_mib_per_min"] = limits.kv_limits.ingress_mib_per_min;
671
+ }
672
+ if (limits.kv_limits.egress_mib_per_min > 0) {
673
+ kv_limits["egress_mib_per_min"] = limits.kv_limits.egress_mib_per_min;
674
+ }
675
+ json_limits["kv"] = kv_limits;
676
+ }
677
+ if (limits.query_limits.enforce) {
678
+ Json::Value query_limits;
679
+ if (limits.query_limits.num_concurrent_requests > 0) {
680
+ query_limits["num_concurrent_requests"] = limits.query_limits.num_concurrent_requests;
681
+ }
682
+ if (limits.query_limits.num_queries_per_min > 0) {
683
+ query_limits["num_queries_per_min"] = limits.query_limits.num_queries_per_min;
684
+ }
685
+ if (limits.query_limits.ingress_mib_per_min > 0) {
686
+ query_limits["ingress_mib_per_min"] = limits.query_limits.ingress_mib_per_min;
687
+ }
688
+ if (limits.query_limits.egress_mib_per_min > 0) {
689
+ query_limits["egress_mib_per_min"] = limits.query_limits.egress_mib_per_min;
690
+ }
691
+ json_limits["query"] = query_limits;
692
+ }
693
+ if (limits.search_limits.enforce) {
694
+ Json::Value fts_limits;
695
+ if (limits.search_limits.num_concurrent_requests > 0) {
696
+ fts_limits["num_concurrent_requests"] = limits.search_limits.num_concurrent_requests;
697
+ }
698
+ if (limits.search_limits.num_queries_per_min > 0) {
699
+ fts_limits["num_queries_per_min"] = limits.search_limits.num_queries_per_min;
700
+ }
701
+ if (limits.search_limits.ingress_mib_per_min > 0) {
702
+ fts_limits["ingress_mib_per_min"] = limits.search_limits.ingress_mib_per_min;
703
+ }
704
+ if (limits.search_limits.egress_mib_per_min > 0) {
705
+ fts_limits["egress_mib_per_min"] = limits.search_limits.egress_mib_per_min;
706
+ }
707
+ json_limits["fts"] = fts_limits;
708
+ }
709
+ std::string j_limits = Json::FastWriter().write(json_limits);
710
+ body += "&limits=" + j_limits;
711
+ std::string content_type = "application/x-www-form-urlencoded";
712
+
713
+ lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_MANAGEMENT);
714
+ lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_PUT);
715
+ lcb_cmdhttp_path(cmd, path.c_str(), path.size());
716
+ lcb_cmdhttp_body(cmd, body.c_str(), body.size());
717
+ lcb_cmdhttp_content_type(cmd, content_type.c_str(), content_type.size());
718
+
719
+ http_result result{};
720
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_http(instance, &result, cmd));
721
+ lcb_cmdhttp_destroy(cmd);
722
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_wait(instance, LCB_WAIT_DEFAULT));
723
+ ASSERT_STATUS_EQ(LCB_SUCCESS, result.rc);
724
+ }
725
+
726
+ void create_rate_limited_scope(lcb_INSTANCE *instance, const std::string &bucket, std::string &scope,
727
+ const scope_rate_limits &limits)
728
+ {
729
+ (void)lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback);
730
+
731
+ lcb_CMDHTTP *cmd;
732
+ std::string path = "/pools/default/buckets/" + bucket + "/scopes";
733
+ std::string body = "name=" + scope;
734
+ Json::Value json_limits;
735
+ if (limits.kv_scope_limits.enforce) {
736
+ Json::Value kv_limits;
737
+ kv_limits["data_size"] = limits.kv_scope_limits.data_size;
738
+ json_limits["kv"] = kv_limits;
739
+ }
740
+ if (limits.index_scope_limits.enforce) {
741
+ Json::Value index_limits;
742
+ index_limits["num_indexes"] = limits.index_scope_limits.num_indexes;
743
+ json_limits["index"] = index_limits;
744
+ }
745
+ std::string j_limits = Json::FastWriter().write(json_limits);
746
+ body += "&limits=" + j_limits;
747
+ std::string content_type = "application/x-www-form-urlencoded";
748
+
749
+ lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_MANAGEMENT);
750
+ lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_POST);
751
+ lcb_cmdhttp_path(cmd, path.c_str(), path.size());
752
+ lcb_cmdhttp_body(cmd, body.c_str(), body.size());
753
+ lcb_cmdhttp_content_type(cmd, content_type.c_str(), content_type.size());
754
+
755
+ http_result result{};
756
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_http(instance, &result, cmd));
757
+ lcb_cmdhttp_destroy(cmd);
758
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_wait(instance, LCB_WAIT_DEFAULT));
759
+ ASSERT_STATUS_EQ(LCB_SUCCESS, result.rc);
760
+ }
761
+
762
+ void drop_user(lcb_INSTANCE *instance, const std::string &username)
763
+ {
764
+ (void)lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback);
765
+
766
+ lcb_CMDHTTP *cmd;
767
+ std::string path = "/settings/rbac/users/local/" + username;
768
+
769
+ lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_MANAGEMENT);
770
+ lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_DELETE);
771
+ lcb_cmdhttp_path(cmd, path.c_str(), path.size());
772
+
773
+ http_result result{};
774
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_http(instance, &result, cmd));
775
+ lcb_cmdhttp_destroy(cmd);
776
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_wait(instance, LCB_WAIT_DEFAULT));
777
+ ASSERT_STATUS_EQ(LCB_SUCCESS, result.rc);
778
+ }
779
+
780
+ void create_search_index(lcb_INSTANCE *instance, const std::string &index_name, const std::string &type,
781
+ const std::string &source_type, const std::string &source_name)
782
+ {
783
+ (void)lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)http_callback);
784
+
785
+ lcb_CMDHTTP *cmd;
786
+ std::string path = "/api/index/" + index_name;
787
+ Json::Value json_body;
788
+ json_body["name"] = index_name;
789
+ json_body["type"] = type;
790
+ json_body["sourceName"] = source_name;
791
+ json_body["sourceType"] = source_type;
792
+
793
+ auto body = Json::FastWriter().write(json_body);
794
+
795
+ lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_SEARCH);
796
+ lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_PUT);
797
+ lcb_cmdhttp_path(cmd, path.c_str(), path.size());
798
+ lcb_cmdhttp_body(cmd, body.c_str(), body.size());
799
+
800
+ http_result result{};
801
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_http(instance, &result, cmd));
802
+ lcb_cmdhttp_destroy(cmd);
803
+ ASSERT_STATUS_EQ(LCB_SUCCESS, lcb_wait(instance, LCB_WAIT_DEFAULT));
804
+ ASSERT_STATUS_EQ(LCB_SUCCESS, result.rc);
805
+ }
@@ -20,6 +20,8 @@
20
20
  #include <libcouchbase/couchbase.h>
21
21
  #include <libcouchbase/vbucket.h>
22
22
  #include <string>
23
+ #include <memory>
24
+ #include <unordered_map>
23
25
 
24
26
  #define ASSERT_STATUS_EQ(expected, actual) \
25
27
  lcb_STATUS GTEST_CONCAT_TOKEN_(actual_code__, __LINE__) = (actual); \
@@ -212,4 +214,166 @@ void drop_scope(lcb_INSTANCE *instance, const std::string &scope, bool wait = tr
212
214
  void drop_collection(lcb_INSTANCE *instance, const std::string &scope, const std::string &collection, bool wait = true);
213
215
 
214
216
  std::string unique_name(const std::string &);
217
+
218
+ class TestSpan
219
+ {
220
+ public:
221
+ explicit TestSpan(std::string name);
222
+ void SetAttribute(std::string key, std::string value);
223
+ void SetAttribute(std::string key, uint64_t value);
224
+ void End();
225
+
226
+ std::unordered_map<std::string, std::string> str_tags{};
227
+ std::unordered_map<std::string, uint64_t> int_tags{};
228
+ bool finished{false};
229
+ std::string name{};
230
+
231
+ TestSpan *parent{nullptr};
232
+ };
233
+
234
+ class TestTracer
235
+ {
236
+ public:
237
+ TestTracer() = default;
238
+ ~TestTracer();
239
+ std::shared_ptr<TestSpan> StartSpan(std::string name);
240
+
241
+ std::vector<std::shared_ptr<TestSpan>> spans{};
242
+
243
+ void reset();
244
+
245
+ bool set_enabled(bool new_value)
246
+ {
247
+ bool old_value = enabled_;
248
+ enabled_ = new_value;
249
+
250
+ reset();
251
+ destroy_lcb_tracer();
252
+ if (new_value) {
253
+ create_lcb_tracer();
254
+ }
255
+ return old_value;
256
+ }
257
+
258
+ bool enabled() const
259
+ {
260
+ return enabled_;
261
+ }
262
+
263
+ lcbtrace_TRACER *lcb_tracer()
264
+ {
265
+ return lcbtracer_;
266
+ }
267
+
268
+ private:
269
+ void create_lcb_tracer();
270
+ void destroy_lcb_tracer();
271
+
272
+ lcbtrace_TRACER *lcbtracer_{nullptr};
273
+ bool enabled_{false};
274
+ };
275
+
276
+ class TestValueRecorder
277
+ {
278
+ public:
279
+ TestValueRecorder() = default;
280
+ void RecordValue(uint64_t value);
281
+
282
+ std::vector<uint64_t> values{};
283
+ };
284
+
285
+ class TestMeter
286
+ {
287
+ public:
288
+ TestMeter();
289
+ void reset();
290
+ std::shared_ptr<TestValueRecorder> ValueRecorder(std::string name,
291
+ std::unordered_map<std::string, std::string> tags);
292
+
293
+ std::unordered_map<std::string, std::shared_ptr<TestValueRecorder>> recorders{};
294
+
295
+ bool set_enabled(bool new_value)
296
+ {
297
+ bool old_value = enabled_;
298
+ enabled_ = new_value;
299
+
300
+ reset();
301
+ destroy_lcb_meter();
302
+ if (new_value) {
303
+ create_lcb_meter();
304
+ }
305
+ return old_value;
306
+ }
307
+
308
+ bool enabled() const
309
+ {
310
+ return enabled_;
311
+ }
312
+
313
+ lcbmetrics_METER *lcb_meter()
314
+ {
315
+ return lcbmeter_;
316
+ }
317
+
318
+ private:
319
+ void create_lcb_meter();
320
+ void destroy_lcb_meter();
321
+
322
+ lcbmetrics_METER *lcbmeter_{nullptr};
323
+ bool enabled_{false};
324
+ };
325
+
326
+ struct kv_rate_limits {
327
+ uint32_t num_connections{0};
328
+ uint32_t num_ops_per_min{0};
329
+ uint32_t ingress_mib_per_min{0};
330
+ uint32_t egress_mib_per_min{0};
331
+ bool enforce{false};
332
+ };
333
+
334
+ struct query_rate_limits {
335
+ uint32_t ingress_mib_per_min{0};
336
+ uint32_t egress_mib_per_min{0};
337
+ uint32_t num_concurrent_requests{0};
338
+ uint32_t num_queries_per_min{0};
339
+ bool enforce{false};
340
+ };
341
+
342
+ struct search_rate_limits {
343
+ uint32_t ingress_mib_per_min{0};
344
+ uint32_t egress_mib_per_min{0};
345
+ uint32_t num_concurrent_requests{0};
346
+ uint32_t num_queries_per_min{0};
347
+ bool enforce{false};
348
+ };
349
+
350
+ struct rate_limits {
351
+ kv_rate_limits kv_limits{};
352
+ query_rate_limits query_limits{};
353
+ search_rate_limits search_limits{};
354
+ };
355
+
356
+ struct kv_scope_rate_limits {
357
+ uint32_t data_size;
358
+ bool enforce{false};
359
+ };
360
+
361
+ struct index_scope_rate_limits {
362
+ uint32_t num_indexes{0};
363
+ bool enforce{false};
364
+ };
365
+
366
+ struct scope_rate_limits {
367
+ kv_scope_rate_limits kv_scope_limits;
368
+ index_scope_rate_limits index_scope_limits;
369
+ };
370
+
371
+ void enforce_rate_limits(lcb_INSTANCE *instance);
372
+ void create_rate_limited_user(lcb_INSTANCE *instance, const std::string &username, const rate_limits &limits);
373
+ void drop_user(lcb_INSTANCE *instance, const std::string &username);
374
+ void create_rate_limited_scope(lcb_INSTANCE *instance, const std::string &bucket, std::string &scope,
375
+ const scope_rate_limits &limits);
376
+ void create_search_index(lcb_INSTANCE *instance, const std::string &index_name, const std::string &type,
377
+ const std::string &source_type, const std::string &source_name);
378
+
215
379
  #endif
@@ -20,8 +20,6 @@
20
20
  #include <stdio.h>
21
21
 
22
22
  #ifndef _WIN32
23
- #define _XOPEN_SOURCE
24
- #include <stdlib.h>
25
23
  #include <string.h>
26
24
  #include <wordexp.h>
27
25
  #include <fcntl.h> /* O_* */
@@ -51,6 +49,7 @@ static char **clisplit(const char *s)
51
49
  ret[ii] = strdup(p.we_wordv[ii]);
52
50
  }
53
51
  ret[ii] = NULL;
52
+ wordfree(&p);
54
53
  return ret;
55
54
  }
56
55
 
@@ -59,39 +58,44 @@ static int spawn_process_impl(child_process_t *proc)
59
58
  int rv;
60
59
  char **argv;
61
60
 
62
- proc->pid = fork();
63
- if (proc->pid < 0) {
61
+ argv = clisplit(proc->name);
62
+ if (argv == NULL) {
63
+ fprintf(stderr, "Couldn't split arguments: %s\n", proc->name);
64
64
  return -1;
65
65
  }
66
- if (proc->pid > 0) {
67
- return 0;
68
- }
69
-
70
- /** In Child */
71
- argv = clisplit(proc->name);
72
- if (!argv) {
73
- fprintf(stderr, "Couldn't split arguments\n");
74
- exit(EXIT_FAILURE);
66
+ proc->pid = vfork();
67
+ if (proc->pid < 0) {
68
+ for (int i = 0; argv[i] != NULL; ++i) {
69
+ free(argv[i]);
70
+ }
71
+ free(argv);
72
+ return -1;
75
73
  }
76
- if (proc->redirect) {
77
- int fd = open(proc->redirect, O_RDWR | O_CREAT | O_APPEND, 0644);
78
- if (fd < 0) {
79
- perror(proc->redirect);
80
- exit(EXIT_FAILURE);
74
+ if (proc->pid == 0) {
75
+ /** In Child */
76
+ if (proc->redirect) {
77
+ int fd = open(proc->redirect, O_RDWR | O_CREAT | O_APPEND, 0644);
78
+ if (fd < 0) {
79
+ perror(proc->redirect);
80
+ exit(EXIT_FAILURE);
81
+ }
82
+ if (dup2(fd, fileno(stderr)) < 0 || dup2(fd, fileno(stdout)) < 0) {
83
+ perror("dup2");
84
+ exit(EXIT_FAILURE);
85
+ }
86
+ setvbuf(stderr, NULL, _IOLBF, 0);
81
87
  }
82
- if (dup2(fd, fileno(stderr)) < 0 || dup2(fd, fileno(stdout)) < 0) {
83
- perror("dup2");
84
- exit(EXIT_FAILURE);
88
+ rv = execvp(argv[0], argv);
89
+ if (rv < 0) {
90
+ perror(argv[0]);
91
+ return -1;
85
92
  }
86
- setvbuf(stderr, NULL, _IOLBF, 0);
87
93
  }
88
- rv = execvp(argv[0], argv);
89
- if (rv < 0) {
90
- perror(argv[0]);
91
- exit(EXIT_FAILURE);
94
+ for (int i = 0; argv[i] != NULL; ++i) {
95
+ free(argv[i]);
92
96
  }
93
- abort();
94
- return 0; /* make things happy */
97
+ free(argv);
98
+ return 0;
95
99
  }
96
100
 
97
101
  void kill_process(child_process_t *process, int force)
@@ -296,7 +296,6 @@ static int start_mock_server(struct test_server_info *info, char **cmdline)
296
296
 
297
297
  start_mock_process(info, argv);
298
298
  negotiate_mock_connection(info);
299
- sleep(1); /* give it a bit time to initialize itself */
300
299
  return 1;
301
300
  }
302
301
 
@@ -1273,6 +1273,13 @@ void VersionHandler::run()
1273
1273
  #endif
1274
1274
  printf(" SSL Headers: %s\n", OPENSSL_VERSION_TEXT);
1275
1275
  #endif
1276
+ printf(" HAVE_PKCS5_PBKDF2_HMAC: "
1277
+ #ifdef HAVE_PKCS5_PBKDF2_HMAC
1278
+ "yes"
1279
+ #else
1280
+ "no"
1281
+ #endif
1282
+ "\n");
1276
1283
  } else {
1277
1284
  printf(" SSL: NOT SUPPORTED\n");
1278
1285
  }
@@ -82,8 +82,8 @@ class AnalyticsExecutor {
82
82
  }
83
83
  const metricsData = metaData.metrics || {};
84
84
  const metrics = new analyticstypes_1.AnalyticsMetrics({
85
- elapsedTime: utilities_1.goDurationStrToMs(metricsData.elapsedTime) || 0,
86
- executionTime: utilities_1.goDurationStrToMs(metricsData.executionTime) || 0,
85
+ elapsedTime: (0, utilities_1.goDurationStrToMs)(metricsData.elapsedTime) || 0,
86
+ executionTime: (0, utilities_1.goDurationStrToMs)(metricsData.executionTime) || 0,
87
87
  resultCount: metricsData.resultCount || 0,
88
88
  resultSize: metricsData.resultSize || 0,
89
89
  errorCount: metricsData.errorCount || 0,