From 595c1500b0a7157d187d19604d5a3c4ab689070c Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Wed, 6 Mar 2024 18:46:17 -0800 Subject: [PATCH 1/3] update core Change-Id: I4f5aad3852c693909985ef7d286a26b6c66e5681 --- ext/.gitignore | 1 + ext/.idea/vcs.xml | 10 +++++++--- ext/couchbase | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ext/.gitignore b/ext/.gitignore index 403b064c..39422c9e 100644 --- a/ext/.gitignore +++ b/ext/.gitignore @@ -1,4 +1,5 @@ /.idea/sonarlint/ +/.idea/editor.xml /.idea/workspace.xml /build/ /cmake-build-*/ diff --git a/ext/.idea/vcs.xml b/ext/.idea/vcs.xml index c10aafdc..73141661 100644 --- a/ext/.idea/vcs.xml +++ b/ext/.idea/vcs.xml @@ -3,8 +3,12 @@ - - - + + + + + + + \ No newline at end of file diff --git a/ext/couchbase b/ext/couchbase index 59627a00..933e87ee 160000 --- a/ext/couchbase +++ b/ext/couchbase @@ -1 +1 @@ -Subproject commit 59627a0043390ebdb1b876f0d37f29105e8193a4 +Subproject commit 933e87eeab58b0a3f063fc12d93b443eea39cca7 From 28f234e35505d89b29eb48b74581cedc6a012f2a Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Wed, 13 Mar 2024 18:31:00 -0700 Subject: [PATCH 2/3] detect cbdinocluster in bin/console --- bin/console | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/bin/console b/bin/console index 7241283e..a4ee220c 100755 --- a/bin/console +++ b/bin/console @@ -16,6 +16,7 @@ require "bundler/setup" require "irb" +require "open3" require "couchbase" include Couchbase # rubocop:disable Style/MixinUsage for brevity @@ -44,9 +45,38 @@ customer123 = { }, } +def which(name, extra_locations = []) + ENV.fetch("PATH", "") + .split(File::PATH_SEPARATOR) + .prepend(*extra_locations) + .select { |path| File.directory?(path) } + .map { |path| [path, name].join(File::SEPARATOR) + RbConfig::CONFIG["EXEEXT"] } + .find { |file| File.executable?(file) } +end + +def capture_output(*cmd) + output, _, status = Open3.capture3(*cmd) + return unless status.success? + + output.strip! + return if output.empty? + + output +end + +def cbdinocluster_connection_string + cbdinocluster = which("cbdinocluster") + return unless cbdinocluster + + first_cluster = capture_output(cbdinocluster, "ps")[/([-0-9a-f]+) \[State: ready/i, 1] + return unless first_cluster + + capture_output(cbdinocluster, "connstr", first_cluster) +end + def cluster @cluster ||= begin - connection_string = ARGV[0] || ENV.fetch("TEST_CONNECTION_STRING", nil) || "couchbase://localhost" + connection_string = ARGV[0] || ENV.fetch("TEST_CONNECTION_STRING", cbdinocluster_connection_string) || "couchbase://localhost" username = ARGV[1] || ENV.fetch("TEST_USERNAME", nil) || "Administrator" password = ARGV[2] || ENV.fetch("TEST_PASSWORD", nil) || "password" Cluster.connect(connection_string, username, password) From 79627f6401c1b79d6ce8519621d4546e523e94b9 Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Wed, 6 Mar 2024 18:46:27 -0800 Subject: [PATCH 3/3] configure test pipeline on github actions --- .github/workflows/linters.yml | 4 + .github/workflows/tests.yml | 734 ++++++++++++++++++ .idea/vcs.xml | 14 +- bin/jenkins/repackage-extension.rb | 7 +- lib/couchbase/options.rb | 1 + .../cache_delete_matched_behavior.rb | 3 + .../behaviors/local_cache_behavior.rb | 2 + test/active_support/cache_store_test.rb | 6 + test/collection_manager_test.rb | 36 +- test/mock_helper.rb | 9 +- test/query_index_manager_test.rb | 12 +- test/scope_search_index_manager_test.rb | 15 +- test/test_helper.rb | 18 +- test/utils/consistency_helper.rb | 4 +- 14 files changed, 834 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 34183cc4..4d9b9263 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -52,6 +52,10 @@ jobs: sudo bash -c "echo 'deb https://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' >> /etc/apt/sources.list" sudo apt-get update -y sudo apt-get install -y clang-11 clang-tools-11 + - uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 2G + key: ${{ github.job }} - name: Run scan build run: ./bin/check-clang-static-analyzer env: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..78b7cf72 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,734 @@ +name: tests + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + source: + runs-on: ubuntu-22.04 + outputs: + gem_version: ${{ steps.build_gem.outputs.gem_version }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + fetch-tags: true + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + bundler-cache: true + - name: Build + id: build_gem + run: | + COMMITS_SINCE_LAST_TAG=$(git describe --tags --always --long | awk -F '-' '{print $2}') + ruby bin/jenkins/patch-version.rb ${COMMITS_SINCE_LAST_TAG} + GEM_VERSION=$(ruby -r ./lib/couchbase/version.rb -e "puts Couchbase::VERSION[:sdk]") + echo "gem_version=${GEM_VERSION}" >> "$GITHUB_OUTPUT" + bundle exec rake build + - name: RDoc + run: | + cat > patch-readme.rb <> $GITHUB_PATH + - name: Initialize cbdinocluster + run: | + cbdinocluster -v init --auto + - name: Start couchbase cluster + env: + CLUSTERCONFIG: | + nodes: + - count: 3 + version: ${{ matrix.server }} + services: + - kv + - n1ql + - index + - fts + - cbas + docker: + kv-memory: 1500 + run: | + CLUSTER_ID=$(cbdinocluster -v allocate --def="${CLUSTERCONFIG}") + CONNECTION_STRING=$(cbdinocluster -v connstr "${CLUSTER_ID}") + cbdinocluster -v buckets add ${CLUSTER_ID} default --ram-quota-mb=100 --flush-enabled=true + cbdinocluster -v buckets load-sample ${CLUSTER_ID} travel-sample + echo "CLUSTER_ID=${CLUSTER_ID}" >> "$GITHUB_ENV" + echo "TEST_CONNECTION_STRING=${CONNECTION_STRING}?dump_configuration=true" >> "$GITHUB_ENV" + - uses: actions/download-artifact@v4 + with: + name: couchbase-${{ needs.source.outputs.gem_version }}-x86_64-linux + - uses: actions/download-artifact@v4 + with: + name: scripts-${{ needs.source.outputs.gem_version }} + - uses: actions/download-artifact@v4 + with: + name: tests-${{ needs.source.outputs.gem_version }} + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Install + run: | + COUCHBASE_GEM_PATH=$(realpath couchbase-*.gem) + UNPACKED_GEM_PATH=$(gem unpack ${COUCHBASE_GEM_PATH} | grep "Unpacked gem" | cut -d "'" -f 2) + gem unpack --spec --target ${UNPACKED_GEM_PATH} ${COUCHBASE_GEM_PATH} + ruby -i.bak -pe "gsub(/gemspec/, 'gem \"couchbase\", path: \"${UNPACKED_GEM_PATH}\"')" Gemfile + bundle install + bundle exec ruby -r bundler/setup -r couchbase -e 'pp Couchbase::VERSION, Couchbase::BUILD_INFO' + - name: Test + env: + TEST_SERVER_VERSION: ${{ matrix.server }} + run: | + bundle exec rake test + - name: Publish Test Report + uses: mikepenz/action-junit-report@v4.1.0 + if: always() + with: + check_name: 🐧server, ee-${{ matrix.server }} + report_paths: test/reports/*.xml + require_tests: true + annotate_only: true + - name: Collect server logs + timeout-minutes: 15 + if: failure() + run: | + mkdir -p logs + cbdinocluster -v collect-logs $CLUSTER_ID ./logs + - name: Upload logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ${{ github.job }}-${{ github.run_attempt }}-${{ matrix.server }}-logs + path: | + logs/* + test/**/*.{log,xml} + retention-days: 5 + + windows_x64: + needs: source + runs-on: windows-2019 + strategy: + fail-fast: false + matrix: + ruby: + - '3.1' + - '3.2' + - '3.3' + steps: + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: Install dependencies + run: | + ridk exec pacman --sync --noconfirm --needed mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-go mingw-w64-ucrt-x86_64-nasm mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-toolchain + - uses: actions/download-artifact@v4 + with: + name: couchbase-${{ needs.source.outputs.gem_version }} + - name: Precompile + env: + CB_STATIC_BORINGSSL: 1 + CB_STATIC_STDLIB: 1 + CB_REMOVE_EXT_DIRECTORY: 1 + run: | + gem install gem-compiler + gem compile --prune couchbase-${{ needs.source.outputs.gem_version }}.gem + - uses: actions/upload-artifact@v4 + with: + retention-days: 1 + name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw-${{ matrix.ruby }} + path: | + *-x64-mingw*.gem + + repackage_windows_x64: + needs: + - source + - windows_x64 + runs-on: windows-2019 + steps: + - uses: actions/download-artifact@v4 + with: + name: scripts-${{ needs.source.outputs.gem_version }} + - uses: actions/download-artifact@v4 + with: + path: pkg/binary/3.1 + name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw-3.1 + - uses: actions/download-artifact@v4 + with: + path: pkg/binary/3.2 + name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw-3.2 + - uses: actions/download-artifact@v4 + with: + path: pkg/binary/3.3 + name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw-3.3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Repackage + run: | + ruby bin/jenkins/repackage-extension.rb + - uses: actions/upload-artifact@v4 + with: + name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw + path: | + pkg/fat/*.gem + + ###### + ###### TODO: Windows builds have issues with ASIO mix with Ruby interpreter around socket API + ###### ASIO creates sockets using 'WSASocket', but connect using with 'connect' (sync) + ###### or 'WSAIoctl' with ConnectEx GUID. Typically it works, unless these APIs invoked + ###### inside Ruby process compiled with MinGW/ucrt. + ###### + ###### The issue tracked here: https://issues.couchbase.com/browse/RCBC-480 + ###### + + # mock_windows_x64: + # timeout-minutes: 15 + # needs: + # - source + # - repackage_windows_x64 + # runs-on: windows-2019 + # strategy: + # fail-fast: false + # matrix: + # ruby: + # - '3.1' + # - '3.2' + # - '3.3' + # steps: + # - uses: actions/download-artifact@v4 + # with: + # name: couchbase-${{ needs.source.outputs.gem_version }}-x64-mingw + # - uses: actions/download-artifact@v4 + # with: + # name: scripts-${{ needs.source.outputs.gem_version }} + # - uses: actions/download-artifact@v4 + # with: + # name: tests-${{ needs.source.outputs.gem_version }} + # - uses: ruby/setup-ruby@v1 + # with: + # ruby-version: ${{ matrix.ruby }} + # - name: Install + # shell: pwsh + # run: | + # $COUCHBASE_GEM_PATH = Get-ChildItem -Filter 'couchbase-*.gem' | Select-Object -ExpandProperty FullName -First 1 + # $UNPACKED_GEM_PATH = (gem unpack $COUCHBASE_GEM_PATH | Select-String "Unpacked gem: '(.*)'").Matches.Groups[1].Value + # gem unpack --spec --target $UNPACKED_GEM_PATH $COUCHBASE_GEM_PATH + # ruby -ibak -pe "gsub(/gemspec/, 'gem `"couchbase`", path: `"${UNPACKED_GEM_PATH}`"')" Gemfile + # bundle install + # bundle exec ruby -r bundler/setup -r couchbase -e 'pp Couchbase::VERSION, Couchbase::BUILD_INFO' + # bundle exec rake test diff --git a/.idea/vcs.xml b/.idea/vcs.xml index fe71edbe..76dafdf5 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,20 +2,8 @@ + - - - - - - - - - - - - - \ No newline at end of file diff --git a/bin/jenkins/repackage-extension.rb b/bin/jenkins/repackage-extension.rb index a3cf22fd..7d046dc7 100755 --- a/bin/jenkins/repackage-extension.rb +++ b/bin/jenkins/repackage-extension.rb @@ -8,6 +8,11 @@ require "rubygems/installer" require "rubygems/package" +def run(*args) + _, status = Open3.capture2e(*args) + status.success? +end + module Gem class Collector def initialize(gemfiles) @@ -38,7 +43,7 @@ def bundle(target_dir) new_path = File.join(new_dirname, basename).gsub(installer.spec.full_gem_path, first_gemspec.full_gem_path) FileUtils.mkdir_p(File.dirname(new_path)) FileUtils.mv(path, new_path) - system("strip", "--strip-all", new_path) || system("strip", new_path) + run("strip", "--strip-all", new_path) || run("strip", new_path) file = new_path.sub("#{first_gemspec.full_gem_path}/", "") puts "Adding '#{file}' to gemspec" first_gemspec.files.push file diff --git a/lib/couchbase/options.rb b/lib/couchbase/options.rb index 614b8b02..a68b67a4 100644 --- a/lib/couchbase/options.rb +++ b/lib/couchbase/options.rb @@ -14,6 +14,7 @@ require "couchbase/utils/time" require "couchbase/config_profiles" +require "couchbase/json_transcoder" module Couchbase # Definition of the Option classes for data APIs diff --git a/test/active_support/behaviors/cache_delete_matched_behavior.rb b/test/active_support/behaviors/cache_delete_matched_behavior.rb index 35b6371a..bd0a4f19 100644 --- a/test/active_support/behaviors/cache_delete_matched_behavior.rb +++ b/test/active_support/behaviors/cache_delete_matched_behavior.rb @@ -4,6 +4,9 @@ module CacheDeleteMatchedBehavior def test_delete_matched skip("#{name}: The #{Couchbase::Protostellar::NAME} protocol does not support consistent_with yet") if env.protostellar? skip("#{name}: delete_matched is not stable on 6.x servers, version=#{env.server_version}") if use_caves? || env.server_version.mad_hatter? + + ensure_primary_index! + begin @cache.delete_matched("*") rescue NotImplementedError diff --git a/test/active_support/behaviors/local_cache_behavior.rb b/test/active_support/behaviors/local_cache_behavior.rb index c13cf82f..e54e0d4f 100644 --- a/test/active_support/behaviors/local_cache_behavior.rb +++ b/test/active_support/behaviors/local_cache_behavior.rb @@ -33,6 +33,8 @@ def test_clear_also_clears_local_cache skip("#{name}: The #{Couchbase::Protostellar::NAME} protocol does not support consistent_with yet") if env.protostellar? skip("#{name}: CAVES does not support query service yet for clear in cache adapter") if use_caves? + ensure_primary_index! + key = SecureRandom.uuid @cache.with_local_cache do @cache.write(key, SecureRandom.alphanumeric) diff --git a/test/active_support/cache_store_test.rb b/test/active_support/cache_store_test.rb index 81d10128..27d6d2c0 100644 --- a/test/active_support/cache_store_test.rb +++ b/test/active_support/cache_store_test.rb @@ -33,6 +33,9 @@ def test_clear skip("#{name}: The #{Couchbase::Protostellar::NAME} protocol does not support consistent_with yet") if env.protostellar? skip("#{name}: CAVES does not support query service yet for clear in cache adapter") if use_caves? + # clear uses N1QL and primary index by default + ensure_primary_index! + foo = uniq_id(:foo) @cache.write(foo, "value_foo") @cache.clear @@ -91,6 +94,9 @@ def test_delete_matched skip("#{name}: delete_matched is not stable on 6.x servers, version=#{env.server_version}") if env.server_version.mad_hatter? skip("The server #{env.server_version} does not support delete_matched") unless env.server_version.supports_regexp_matches? + + ensure_primary_index! + foo = uniq_id(:foo) @cache.write(foo, "value_foo") bar = uniq_id(:bar) diff --git a/test/collection_manager_test.rb b/test/collection_manager_test.rb index 18b7c6d6..500299cb 100644 --- a/test/collection_manager_test.rb +++ b/test/collection_manager_test.rb @@ -58,8 +58,6 @@ def get_collection(scope_name, collection_name, mgr = nil) end def setup - skip("#{name}: The server does not support collections") unless env.server_version.supports_collections? - connect @used_scopes = [] @bucket = @cluster.bucket(env.bucket) @@ -87,15 +85,19 @@ def teardown end def test_create_scope + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name @collection_manager.create_scope(scope_name) env.consistency.wait_until_scope_present(env.bucket, scope_name) scope = get_scope(scope_name) - refute_nil scope + refute_nil scope, "scope #{scope_name} should be available by now" end def test_drop_scope + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name @collection_manager.create_scope(scope_name) env.consistency.wait_until_scope_present(env.bucket, scope_name) @@ -111,6 +113,8 @@ def test_drop_scope end def test_create_collection + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + coll_names = %w[coll-1 coll-2 coll-3] scope_name = get_scope_name @collection_manager.create_scope(scope_name) @@ -127,6 +131,8 @@ def test_create_collection end def test_drop_collection + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + coll_names = %w[coll-1 coll-2 coll-3] scope_name = get_scope_name @collection_manager.create_scope(scope_name) @@ -150,6 +156,8 @@ def test_drop_collection end def test_create_collection_already_exists + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + coll_name = 'coll-1' scope_name = get_scope_name @collection_manager.create_scope(scope_name) @@ -166,6 +174,8 @@ def test_create_collection_already_exists end def test_create_collection_scope_does_not_exist + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + coll_name = 'coll-1' scope_name = 'does-not-exist' @@ -185,6 +195,8 @@ def test_create_collection_scope_does_not_exist end def test_create_scope_already_exists + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name @collection_manager.create_scope(scope_name) env.consistency.wait_until_scope_present(env.bucket, scope_name) @@ -197,6 +209,8 @@ def test_create_scope_already_exists end def test_drop_scope_does_not_exist + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = 'does-not-exist' assert_raises(Error::ScopeNotFound) do @@ -205,6 +219,8 @@ def test_drop_scope_does_not_exist end def test_drop_collection_does_not_exist + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name coll_name = 'does-not-exist' @collection_manager.create_scope(scope_name) @@ -218,6 +234,8 @@ def test_drop_collection_does_not_exist end def test_drop_collection_scope_does_not_exist + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = 'does-not-exist' coll_name = 'does-not-exist' @@ -334,6 +352,8 @@ def test_update_collection_history_retention_unsupported end def test_create_collection_max_expiry + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name collection_name = 'testcoll' @collection_manager.create_scope(scope_name) @@ -370,6 +390,7 @@ def test_create_collection_max_expiry end def test_create_collection_max_expiry_no_expiry + skip("#{name}: The server does not support collections") if use_caves? skip("#{name}: The #{Couchbase::Protostellar::NAME} protocol does not support setting max_expiry to -1 yet") if env.protostellar? unless env.server_version.supports_collection_max_expiry_set_to_no_expiry? skip("#{name}: The server does not support setting max_expiry to -1") @@ -404,7 +425,7 @@ def test_create_collection_max_expiry_no_expiry_not_supported env.consistency.wait_until_scope_present(env.bucket, scope_name) scope = get_scope(scope_name) - assert scope + assert scope, "the scope \"#{scope_name}\" must exist" settings = Management::CreateCollectionSettings.new(max_expiry: -1) @@ -414,6 +435,8 @@ def test_create_collection_max_expiry_no_expiry_not_supported end def test_create_collection_max_expiry_invalid + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name collection_name = 'testcoll' @collection_manager.create_scope(scope_name) @@ -545,6 +568,7 @@ def test_update_collection_max_expiry_no_expiry_not_supported def test_update_collection_max_expiry_invalid skip("#{name}: CAVES does not support update_collection") if use_caves? + skip("#{name}: The server does not support collections") unless env.server_version.supports_collections? skip("#{name}: The #{Couchbase::Protostellar::NAME} protocol does not support update_collection") if env.protostellar? scope_name = get_scope_name @@ -608,6 +632,8 @@ def test_update_collection_scope_does_not_exist end def test_create_collection_deprecated + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name coll_name = 'coll-1' @collection_manager.create_scope(scope_name) @@ -626,6 +652,8 @@ def test_create_collection_deprecated end def test_drop_collection_deprecated + skip("#{name}: The server does not support collections") unless use_caves? || env.server_version.supports_collections? + scope_name = get_scope_name coll_name = 'coll-1' @collection_manager.create_scope(scope_name) diff --git a/test/mock_helper.rb b/test/mock_helper.rb index 2f70346b..5868456c 100755 --- a/test/mock_helper.rb +++ b/test/mock_helper.rb @@ -37,8 +37,8 @@ def download_mock(url = caves_url) raise "Unexpected content type: #{resp['content-type']}" if resp["content-type"] != "application/octet-stream" FileUtils.mkdir_p(caves_dir, verbose: verbose?) - File.write(mock_path, resp.body) - FileUtils.chmod("a+x", mock_path, verbose: verbose?) + File.write(mock_path, resp.body, binmode: true) + FileUtils.chmod("a+x", mock_path, verbose: verbose?) unless windows? when Net::HTTPRedirection download_mock(resp["location"]) else @@ -214,6 +214,11 @@ def open_control_socket @control_sock = TCPServer.new("127.0.0.1", 0) @control_sock.listen(10) _, @control_port, = @control_sock.addr + rescue Socket::ResolutionError => e + backoff_delay = 0.1 + puts "--- #{e.message}, retrying after #{backoff_delay} seconds" + sleep backoff_delay + retry end def control_port diff --git a/test/query_index_manager_test.rb b/test/query_index_manager_test.rb index 0fddd9d9..1af92e28 100644 --- a/test/query_index_manager_test.rb +++ b/test/query_index_manager_test.rb @@ -30,12 +30,14 @@ def setup ) env.consistency.wait_until_bucket_present(@bucket_name) retry_for_duration(expected_errors: [Error::BucketNotFound]) do - @bucket = @cluster.bucket('query-idx-test-bucket') + @bucket = @cluster.bucket(@bucket_name) end # Add a scope in the bucket to verify it has been created - retry_for_duration(expected_errors: [Error::BucketNotFound]) do - @bucket.collections.create_scope("test-scope") + if env.server_version.supports_collections? + retry_for_duration(expected_errors: [Error::BucketNotFound]) do + @bucket.collections.create_scope("test-scope") + end end @idx_mgr = @cluster.query_indexes @@ -48,6 +50,8 @@ def teardown end def test_get_all_indexes + skip("#{name}: CAVES does not support query service yet") if use_caves? + index_names = [uniq_id(:foo), uniq_id(:bar)] index_names.each { |idx_name| @idx_mgr.create_index(@bucket_name, idx_name, ["foo"]) } @@ -60,6 +64,8 @@ def test_get_all_indexes end def test_query_indexes + skip("#{name}: CAVES does not support query service yet") if use_caves? + @idx_mgr.create_primary_index(@bucket_name) @idx_mgr.create_index(@bucket_name, "test_index", ["test"]) res1 = @idx_mgr.get_all_indexes(@bucket_name) diff --git a/test/scope_search_index_manager_test.rb b/test/scope_search_index_manager_test.rb index 6f1e649e..d075dacc 100644 --- a/test/scope_search_index_manager_test.rb +++ b/test/scope_search_index_manager_test.rb @@ -19,10 +19,6 @@ class ScopeSearchIndexManagerTest < Minitest::Test include TestUtilities def setup - unless env.server_version.supports_scoped_search_indexes? - skip("skipped for (#{env.server_version}) as the ScopeSearchIndexManagerTest requires scoped search index support") - end - @index_names = [] connect @@ -47,6 +43,11 @@ def get_search_index_name end def test_index_not_found + skip("#{name}: CAVES does not support query service yet") if use_caves? + unless env.server_version.supports_scoped_search_indexes? + skip("skipped for (#{env.server_version}) as the ScopeSearchIndexManagerTest requires scoped search index support") + end + [ [:drop_index, ["test-index"]], [:get_indexed_documents_count, ["test-index"]], @@ -64,6 +65,11 @@ def test_index_not_found end def test_index_crud + skip("#{name}: CAVES does not support query service yet") if use_caves? + unless env.server_version.supports_scoped_search_indexes? + skip("skipped for (#{env.server_version}) as the ScopeSearchIndexManagerTest requires scoped search index support") + end + index_name = uniq_id(:scope_idx) @mgr.upsert_index( @@ -109,6 +115,7 @@ def setup skip("Test requires not having scoped search index support") if env.server_version.supports_scoped_search_indexes? connect + skip("#{name}: CAVES does not support query service yet") if use_caves? @bucket = @cluster.bucket(env.bucket) @scope = @bucket.default_scope @mgr = @scope.search_indexes diff --git a/test/test_helper.rb b/test/test_helper.rb index 60130c9b..a8315d9f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -31,6 +31,8 @@ require_relative 'utils/consistency_helper' +require "couchbase/management" + class ServerVersion def initialize(version_string, developer_preview: false) @version = Gem::Version.create(version_string.sub(/-\w+$/, "")) @@ -218,8 +220,18 @@ def connect(options = Cluster::ClusterOptions.new) @cluster = Cluster.connect(env.connection_string, options) end + def ensure_primary_index! + @cluster ||= connect + index_manager = @cluster.query_indexes + index_manager.create_primary_index(env.bucket, Management::Options::Query::CreatePrimaryIndex.new(ignore_if_exists: true)) + sleep 0.1 while index_manager.get_all_indexes(env.bucket).none? { |idx| idx.name == "#primary" && idx.state == :online } + end + def disconnect - @cluster.disconnect if defined? @cluster + return unless defined?(@cluster) && @cluster + + @cluster.disconnect + @cluster = nil end # @param [Float] duration in seconds with fractions @@ -277,8 +289,8 @@ def retry_until_error(error:, duration: 10, backoff: 1) require "minitest/reporters" Minitest::Reporters.use!( [ - Minitest::Reporters::SpecReporter.new, - Minitest::Reporters::JUnitReporter.new, + Minitest::Reporters::SpecReporter.new(print_failure_summary: true), + Minitest::Reporters::JUnitReporter.new(Minitest::Reporters::JUnitReporter::DEFAULT_REPORTS_DIR, true, include_timestamp: true), ] ) end diff --git a/test/utils/consistency_helper.rb b/test/utils/consistency_helper.rb index 91ee579e..192ef70a 100644 --- a/test/utils/consistency_helper.rb +++ b/test/utils/consistency_helper.rb @@ -55,7 +55,9 @@ def fetch_hosts(management_endpoint, timeout: DEFAULT_TIMEOUT_SECS) def wait_until_bucket_present(name, timeout: DEFAULT_TIMEOUT_SECS) wait_until(timeout, "Bucket `#{name}` is not present in all nodes") do - resource_is_present("pools/default/buckets/#{name}") + resource_satisfies_predicate("pools/default/buckets/#{name}") do |resp| + resp["nodes"].all? { |node| node["status"] == "healthy" && node["clusterMembership"] == "active" } + end end end