From 15700fdd7a151aacceb4850bc238e467d943250a Mon Sep 17 00:00:00 2001 From: Joshua Young Date: Tue, 17 Jun 2025 10:19:10 +1000 Subject: [PATCH] Update CI workflow matrix --- .github/workflows/ci.yml | 71 ++++++++++++++++++++----------- Gemfile | 3 +- faulty.gemspec | 2 +- lib/faulty/patch/elasticsearch.rb | 15 ++++++- spec/patch/elasticsearch_spec.rb | 30 +++++++++++-- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edb723b..80594d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,30 +12,46 @@ jobs: strategy: fail-fast: false matrix: - ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', jruby-head, truffleruby-head] - redis: ['4'] - search: [['opensearch-ruby:2.1.0', 'opensearchproject/opensearch:2.2.1']] - include: - # Redis 3 - - ruby: '2.7' - redis: '3' - search: ['opensearch-ruby:2.1.0', 'opensearchproject/opensearch:2.2.1'] - # Opensearch 1.0 - - ruby: '2.7' - redis: '4' - search: ['opensearch-ruby:1.0.1', 'opensearchproject/opensearch:1.0.1'] - # Elasticsearch 7.13 - - ruby: '2.7' - redis: '4' - search: ['elasticsearch:7.13.3', 'elasticsearch:7.13.4'] - # Redis 5 - - ruby: '2.7' + ruby: ['2.3', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', head, jruby-head, truffleruby-head] + redis: ['4', '5'] + search: [ + ['opensearch-ruby:1', 'opensearchproject/opensearch:1'], + ['opensearch-ruby:2', 'opensearchproject/opensearch:2'], + ['opensearch-ruby:3', 'opensearchproject/opensearch:3'], + ['elasticsearch:7', 'elasticsearch:7.17.28'], + ['elasticsearch:8', 'elasticsearch:8.18.2'], + ['elasticsearch:9', 'elasticsearch:9.0.2'] + ] + exclude: + # redis 5.x requires ruby >= 2.5 + - ruby: '2.3' + redis: '5' + - ruby: '2.4' redis: '5' - search: ['opensearch-ruby:2.1.0', 'opensearchproject/opensearch:2.2.1'] - # Ruby 2.3 & Elasticsearch 7.5 + # opensearch-ruby 1.x requires ruby >= 2.4 + - ruby: '2.3' + search: ['opensearch-ruby:1', 'opensearchproject/opensearch:1'] + - ruby: '2.3' + search: ['opensearch-ruby:2', 'opensearchproject/opensearch:2'] + - ruby: '2.3' + search: ['opensearch-ruby:3', 'opensearchproject/opensearch:3'] + # opensearch-ruby 3.x requires ruby >= 2.5 + - ruby: '2.3' + search: ['opensearch-ruby:3', 'opensearchproject/opensearch:3'] + - ruby: '2.4' + search: ['opensearch-ruby:3', 'opensearchproject/opensearch:3'] + # elasticsearch 8.x requires ruby >= 2.5 + - ruby: '2.3' + search: ['elasticsearch:8', 'elasticsearch:8.18.2'] + - ruby: '2.4' + search: ['elasticsearch:8', 'elasticsearch:8.18.2'] + # elasticsearch 9.x requires ruby >= 2.6 - ruby: '2.3' - redis: '4' - search: ['elasticsearch:7.5.0', 'elasticsearch:7.13.4'] + search: ['elasticsearch:9', 'elasticsearch:9.0.2'] + - ruby: '2.4' + search: ['elasticsearch:9', 'elasticsearch:9.0.2'] + - ruby: '2.5' + search: ['elasticsearch:9', 'elasticsearch:9.0.2'] services: redis: image: redis @@ -47,7 +63,12 @@ jobs: - 9200:9200 env: discovery.type: single-node + # Disable security for OpenSearch plugins.security.disabled: ${{ contains(matrix.search[1], 'opensearch') && 'true' || '' }} + # OpenSearch 2.12.0 removed the default admin password + OPENSEARCH_INITIAL_ADMIN_PASSWORD: ${{secrets.OPENSEARCH_INITIAL_ADMIN_PASSWORD}} + # Disable security for Elasticsearch 8.x and 9.x + xpack.security.enabled: ${{ contains(matrix.search[1], 'elasticsearch') && 'false' || '' }} options: >- --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=3s @@ -81,7 +102,7 @@ jobs: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: - ruby-version: '2.7' + ruby-version: '3.4' bundler-cache: true - run: bundle exec rubocop @@ -91,7 +112,7 @@ jobs: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: - ruby-version: '2.7' + ruby-version: '3.4' bundler-cache: true - run: bin/yardoc --fail-on-warning @@ -102,7 +123,7 @@ jobs: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: - ruby-version: '2.7' + ruby-version: '3.4' bundler-cache: true - run: bin/check-version diff --git a/Gemfile b/Gemfile index 5851b7d..a507816 100644 --- a/Gemfile +++ b/Gemfile @@ -36,8 +36,7 @@ end if ENV['SEARCH_GEM'] name, version = ENV['SEARCH_GEM'].split(':') - name = 'opensearch-ruby' if name == 'opensearch' gem name, "~> #{version}" else - gem 'opensearch-ruby', '~> 2.1' + gem 'opensearch-ruby' end diff --git a/faulty.gemspec b/faulty.gemspec index 94db015..b59ca15 100644 --- a/faulty.gemspec +++ b/faulty.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| # Other non-essential development dependencies go in the Gemfile. spec.add_development_dependency 'connection_pool', '~> 2.0' spec.add_development_dependency 'json' - spec.add_development_dependency 'redis', '>= 3.0' + spec.add_development_dependency 'redis', '>= 4.0' spec.add_development_dependency 'rspec', '~> 3.8' spec.add_development_dependency 'timecop', '>= 0.9' end diff --git a/lib/faulty/patch/elasticsearch.rb b/lib/faulty/patch/elasticsearch.rb index 1146bee..ff73250 100644 --- a/lib/faulty/patch/elasticsearch.rb +++ b/lib/faulty/patch/elasticsearch.rb @@ -43,7 +43,12 @@ module ServerError; end ::OpenSearch else require 'elasticsearch' - ::Elasticsearch + if Gem.loaded_specs['elastic-transport'] + require 'elastic-transport' + ::Elastic + else + ::Elasticsearch + end end # We will freeze this after adding the dynamic error classes @@ -100,6 +105,14 @@ class Client end end end +elsif Gem.loaded_specs['elastic-transport'] + module Elastic + module Transport + class Client + prepend(Faulty::Patch::Elasticsearch) + end + end + end else module Elasticsearch module Transport diff --git a/spec/patch/elasticsearch_spec.rb b/spec/patch/elasticsearch_spec.rb index e9ad84b..d7efaf6 100644 --- a/spec/patch/elasticsearch_spec.rb +++ b/spec/patch/elasticsearch_spec.rb @@ -15,7 +15,11 @@ end def build_client(**options) - patched_module::Client.new(options) + if Gem.loaded_specs['opensearch-ruby'] + ::OpenSearch::Client.new(options) + else + ::Elasticsearch::Client.new(options) + end end it 'captures patched transport error' do @@ -24,7 +28,13 @@ def build_client(**options) expect(error).to be_a(patched_module::Transport::Transport::Error) expect(error.class).to eq(Faulty::Patch::Elasticsearch::Error::CircuitFailureError) expect(error).to be_a(Faulty::CircuitErrorBase) - expect(error.cause).to be_a(Faraday::ConnectionFailed) + expect(error.cause).to be_a( + if Gem.loaded_specs['elastic-transport'] + Elastic::Transport::Transport::Error + else + Faraday::ConnectionFailed + end + ) end expect(faulty.circuit('elasticsearch').status.failure_rate).to eq(1) end @@ -43,7 +53,13 @@ def build_client(**options) it 'does not capture transport error for unpatched client' do expect { unpatched_bad_client.perform_request('GET', '_cluster/state') } - .to raise_error(Faraday::ConnectionFailed) + .to raise_error( + if Gem.loaded_specs['elastic-transport'] + Elastic::Transport::Transport::Error + else + Faraday::ConnectionFailed + end + ) expect(faulty.circuit('elasticsearch').status.failure_rate).to eq(0) end @@ -51,7 +67,13 @@ def build_client(**options) expect { bad_client_unpatched_errors.perform_request('GET', '_cluster/state') } .to raise_error do |error| expect(error.class).to eq(Faulty::CircuitFailureError) - expect(error.cause).to be_a(Faraday::ConnectionFailed) + expect(error.cause).to be_a( + if Gem.loaded_specs['elastic-transport'] + Elastic::Transport::Transport::Error + else + Faraday::ConnectionFailed + end + ) end expect(faulty.circuit('elasticsearch').status.failure_rate).to eq(1) end