Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 46 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still going to be a pretty big matrix with a lot of CI time, as opposed to the include approach, that just takes a sample of the combinations of supported versions. I'm going to run CI and see what it looks like.

# 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
Expand All @@ -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}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to keep in mind when setting the secret:

Please re-try with a minimum 8 character password and must contain at least one uppercase letter, one lowercase letter, one digit, and one special character that is strong. Password strength can be tested here: https://lowe.github.io/tryzxcvbn

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can just choose something and stick it in the file directly right? There's no reason it needs to be secret.

# 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
Expand Down Expand Up @@ -81,7 +102,7 @@ jobs:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
ruby-version: '3.4'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep these on the lower supported versions I think. Is there a reason you want to change it?

Copy link
Author

@joshuay03 joshuay03 Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thought I'd use the latest ruby, happy to revert back to 2.7.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking is that unless it's unreasonable, we should support dev tooling on our supported ruby versions. One way to check if that's the case is by using the older ruby to run it in CI. I think there's a limitation of Rubocop that prevents using the oldest version, and that's how I ended up with 2.7.

Of course, we might consider dropping support for some older ones, but hasn't been important yet since older support has been trivial.

bundler-cache: true
- run: bundle exec rubocop

Expand All @@ -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

Expand All @@ -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

Expand Down
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion faulty.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to drop support for 3? That's going to be a breaking change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 wasn't running in CI, so I opted to drop it instead of adding it there. But you're right, that would warrant a separate PR.

spec.add_development_dependency 'rspec', '~> 3.8'
spec.add_development_dependency 'timecop', '>= 0.9'
end
15 changes: 14 additions & 1 deletion lib/faulty/patch/elasticsearch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
30 changes: 26 additions & 4 deletions spec/patch/elasticsearch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
end

def build_client(**options)
patched_module::Client.new(options)
if Gem.loaded_specs['opensearch-ruby']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable, but patched_module should already do the right thing here right?

::OpenSearch::Client.new(options)
else
::Elasticsearch::Client.new(options)
end
end

it 'captures patched transport error' do
Expand All @@ -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
Expand All @@ -43,15 +53,27 @@ 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

it 'raises unpatched errors if configured to' do
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
Expand Down
Loading